🎖️GitЯра🎖️
examples/simple_repeater/MyMesh.cpp 890a2e2cffa98dea3ca88db3c3aba72ef23ff3f7 (890a2e2c) Text, 50.22 KB
Tff7b72#Tff7b72include T8b949e"MyMesh.h"
Tff7b72#Tff7b72include T8b949e<algorithm>
T8b949e/* ------------------------------ Config -------------------------------- */
Tff7b72#Tff7b72ifndef LORA_FREQ
Tff7b72#Tff7b72define LORA_FREQ 915.0
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef LORA_BW
Tff7b72#Tff7b72define LORA_BW 250
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef LORA_SF
Tff7b72#Tff7b72define LORA_SF 10
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef LORA_CR
Tff7b72#Tff7b72define LORA_CR 5
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef LORA_TX_POWER
Tff7b72#Tff7b72define LORA_TX_POWER 20
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef ADVERT_NAME
Tff7b72#Tff7b72define ADVERT_NAME "repeater"
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef ADVERT_LAT
Tff7b72#Tff7b72define ADVERT_LAT 0.0
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef ADVERT_LON
Tff7b72#Tff7b72define ADVERT_LON 0.0
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef ADMIN_PASSWORD
Tff7b72#Tff7b72define ADMIN_PASSWORD "password"
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef SERVER_RESPONSE_DELAY
Tff7b72#Tff7b72define SERVER_RESPONSE_DELAY 300
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef TXT_ACK_DELAY
Tff7b72#Tff7b72define TXT_ACK_DELAY 200
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72define FIRMWARE_VER_LEVEL 2
Tff7b72#Tff7b72define REQ_TYPE_GET_STATUS 0x01 T8b949e// same as _GET_STATS
Tff7b72#Tff7b72define REQ_TYPE_KEEP_ALIVE 0x02
Tff7b72#Tff7b72define REQ_TYPE_GET_TELEMETRY_DATA 0x03
Tff7b72#Tff7b72define REQ_TYPE_GET_ACCESS_LIST 0x05
Tff7b72#Tff7b72define REQ_TYPE_GET_NEIGHBOURS 0x06
Tff7b72#Tff7b72define REQ_TYPE_GET_OWNER_INFO 0x07 T8b949e// FIRMWARE_VER_LEVEL >= 2
Tff7b72#Tff7b72define RESP_SERVER_LOGIN_OK 0 T8b949e// response to ANON_REQ
Tff7b72#Tff7b72define ANON_REQ_TYPE_REGIONS 0x01
Tff7b72#Tff7b72define ANON_REQ_TYPE_OWNER 0x02
Tff7b72#Tff7b72define ANON_REQ_TYPE_BASIC 0x03 T8b949e// just remote clock
Tff7b72#Tff7b72define CLI_REPLY_DELAY_MILLIS 600
Tff7b72#Tff7b72define LAZY_CONTACTS_WRITE_DELAY 5000
Tffa657void Td2a8ffMyMesh::putNeighbourTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3Identity Tff7b72&Te6edf3idTb4b4b4, Tffa657uint32_t Te6edf3timestampTb4b4b4, Tffa657float Te6edf3snrTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if MAX_NEIGHBOURS T8b949e// check if neighbours enabled
T8b949e// find existing neighbour, else use least recently updated
Tffa657uint32_t Te6edf3oldest_timestamp Tff7b72= T79c0ff0xFFFFFFFFTb4b4b4;
Te6edf3NeighbourInfo Tff7b72*Te6edf3neighbour Tff7b72= Tff7b72&Te6edf3neighboursTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_NEIGHBOURSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
T8b949e// if neighbour already known, we should update it
Tff7b72if Tb4b4b4(Te6edf3idTb4b4b4.Te6edf3matchesTb4b4b4(Te6edf3neighboursTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3idTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3neighbour Tff7b72= Tff7b72&Te6edf3neighboursTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
T8b949e// otherwise we should update the least recently updated neighbour
Tff7b72if Tb4b4b4(Te6edf3neighboursTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3heard_timestamp Tff7b72< Te6edf3oldest_timestampTb4b4b4) Tb4b4b4{
Te6edf3neighbour Tff7b72= Tff7b72&Te6edf3neighboursTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Te6edf3oldest_timestamp Tff7b72= Te6edf3neighbourTff7b72-Tff7b72>Te6edf3heard_timestampTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// update neighbour info
Te6edf3neighbourTff7b72-Tff7b72>Te6edf3id Tff7b72= Te6edf3idTb4b4b4;
Te6edf3neighbourTff7b72-Tff7b72>Te6edf3advert_timestamp Tff7b72= Te6edf3timestampTb4b4b4;
Te6edf3neighbourTff7b72-Tff7b72>Te6edf3heard_timestamp Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3neighbourTff7b72-Tff7b72>Te6edf3snr Tff7b72= Tb4b4b4(Tffa657int8_tTb4b4b4)Tb4b4b4(Te6edf3snr Tff7b72* T79c0ff4Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tffa657uint8_t Td2a8ffMyMesh::handleLoginReqTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3IdentityTff7b72& Te6edf3senderTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3secretTb4b4b4, Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4, Tffa657bool Te6edf3is_floodTb4b4b4) Tb4b4b4{
Te6edf3ClientInfoTff7b72* Te6edf3client Tff7b72= Tffa657NULLTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// blank password, just check if sender is in ACL
Te6edf3client Tff7b72= Te6edf3aclTb4b4b4.Te6edf3getClientTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3client Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if MESH_DEBUG
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffLogin, sender not in ACLTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3client Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3permsTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3strcmpTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4)Te6edf3dataTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3passwordTb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// check for valid admin password
Te6edf3perms Tff7b72= Te6edf3PERM_ACL_ADMINTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3strcmpTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4)Te6edf3dataTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3guest_passwordTb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// check guest password
Te6edf3perms Tff7b72= Te6edf3PERM_ACL_GUESTTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72#Tff7b72if MESH_DEBUG
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffInvalid password: %sTa5d6ff"Tb4b4b4, Te6edf3dataTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Te6edf3client Tff7b72= Te6edf3aclTb4b4b4.Te6edf3putClientTb4b4b4(Te6edf3senderTb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4; T8b949e// add to contacts (if not already known)
Tff7b72if Tb4b4b4(Te6edf3sender_timestamp Tff7b72<Tff7b72= Te6edf3clientTff7b72-Tff7b72>Te6edf3last_timestampTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffPossible login replay attack!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return T79c0ff0Tb4b4b4; T8b949e// FATAL: client table is full -OR- replay attack
Tb4b4b4}
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffLogin success!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3clientTff7b72-Tff7b72>Te6edf3last_timestamp Tff7b72= Te6edf3sender_timestampTb4b4b4;
Te6edf3clientTff7b72-Tff7b72>Te6edf3last_activity Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3clientTff7b72-Tff7b72>Te6edf3permissions Tff7b72&Tff7b72= Tff7b72~T79c0ff0x03Tb4b4b4;
Te6edf3clientTff7b72-Tff7b72>Te6edf3permissions Tff7b72|Tff7b72= Te6edf3permsTb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3clientTff7b72-Tff7b72>Te6edf3shared_secretTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3perms Tff7b72!Tff7b72= Te6edf3PERM_ACL_GUESTTb4b4b4) Tb4b4b4{ T8b949e// keep number of FS writes to a minimum
Te6edf3dirty_contacts_expiry Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3LAZY_CONTACTS_WRITE_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3is_floodTb4b4b4) Tb4b4b4{
Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_len Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4; T8b949e// need to rediscover out_path
Tb4b4b4}
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeUniqueTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3reply_dataTb4b4b4, Tff7b72&Te6edf3nowTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// response packets always prefixed with timestamp
Te6edf3reply_dataTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72= Te6edf3RESP_SERVER_LOGIN_OKTb4b4b4;
Te6edf3reply_dataTb4b4b4[T79c0ff5Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// Legacy: was recommended keep-alive interval (secs / 16)
Te6edf3reply_dataTb4b4b4[T79c0ff6Tb4b4b4] Tff7b72= Te6edf3clientTff7b72-Tff7b72>Te6edf3isAdminTb4b4b4(Tb4b4b4) Tff7b72? T79c0ff1 Tff7b72: T79c0ff0Tb4b4b4;
Te6edf3reply_dataTb4b4b4[T79c0ff7Tb4b4b4] Tff7b72= Te6edf3clientTff7b72-Tff7b72>Te6edf3permissionsTb4b4b4;
Te6edf3getRNGTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3randomTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff8Tb4b4b4]Tb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// random blob to help packet-hash uniqueness
Te6edf3reply_dataTb4b4b4[T79c0ff12Tb4b4b4] Tff7b72= Te6edf3FIRMWARE_VER_LEVELTb4b4b4; T8b949e// New field
Tff7b72return T79c0ff13Tb4b4b4; T8b949e// reply length
Tb4b4b4}
Tffa657uint8_t Td2a8ffMyMesh::handleAnonRegionsReqTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3IdentityTff7b72& Te6edf3senderTb4b4b4, Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3anon_limiterTb4b4b4.Te6edf3allowTb4b4b4(Te6edf3rtc_clockTb4b4b4.Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// request data has: {reply-path-len}{reply-path}
Te6edf3reply_path_len Tff7b72= Tff7b72*Te6edf3dataTff7b72+Tff7b72+Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3isValidPathLenTb4b4b4(Te6edf3reply_path_lenTb4b4b4)Tb4b4b4) Tff7b72return T79c0ff0Tb4b4b4; T8b949e// reject - bad encoding
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3writePathTb4b4b4(Te6edf3reply_pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3reply_path_lenTb4b4b4)Tb4b4b4;
T8b949e// data += (uint8_t)reply_path_len * reply_path_hash_size;
Te6edf3memcpyTb4b4b4(Te6edf3reply_dataTb4b4b4, Tff7b72&Te6edf3sender_timestampTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// prefix with sender_timestamp, like a tag
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Tff7b72&Te6edf3nowTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// include our clock (for easy clock sync, and packet hash uniqueness)
Tff7b72return T79c0ff8 Tff7b72+ Te6edf3region_mapTb4b4b4.Te6edf3exportNamesToTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff8Tb4b4b4]Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3reply_dataTb4b4b4) Tff7b72- T79c0ff12Tb4b4b4, Te6edf3REGION_DENY_FLOODTb4b4b4)Tb4b4b4; T8b949e// reply length
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tffa657uint8_t Td2a8ffMyMesh::handleAnonOwnerReqTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3IdentityTff7b72& Te6edf3senderTb4b4b4, Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3anon_limiterTb4b4b4.Te6edf3allowTb4b4b4(Te6edf3rtc_clockTb4b4b4.Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// request data has: {reply-path-len}{reply-path}
Te6edf3reply_path_len Tff7b72= Tff7b72*Te6edf3dataTff7b72+Tff7b72+Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3isValidPathLenTb4b4b4(Te6edf3reply_path_lenTb4b4b4)Tb4b4b4) Tff7b72return T79c0ff0Tb4b4b4; T8b949e// reject - bad encoding
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3writePathTb4b4b4(Te6edf3reply_pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3reply_path_lenTb4b4b4)Tb4b4b4;
T8b949e// data += (uint8_t)reply_path_len * reply_path_hash_size;
Te6edf3memcpyTb4b4b4(Te6edf3reply_dataTb4b4b4, Tff7b72&Te6edf3sender_timestampTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// prefix with sender_timestamp, like a tag
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Tff7b72&Te6edf3nowTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// include our clock (for easy clock sync, and packet hash uniqueness)
Te6edf3sprintfTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff8Tb4b4b4]Tb4b4b4, Ta5d6ff"Ta5d6ff%sTffea00\nTa5d6ff%sTa5d6ff"Tb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3owner_infoTb4b4b4)Tb4b4b4;
Tff7b72return T79c0ff8 Tff7b72+ Te6edf3strlenTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff8Tb4b4b4]Tb4b4b4)Tb4b4b4; T8b949e// reply length
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tffa657uint8_t Td2a8ffMyMesh::handleAnonClockReqTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3IdentityTff7b72& Te6edf3senderTb4b4b4, Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3anon_limiterTb4b4b4.Te6edf3allowTb4b4b4(Te6edf3rtc_clockTb4b4b4.Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// request data has: {reply-path-len}{reply-path}
Te6edf3reply_path_len Tff7b72= Tff7b72*Te6edf3dataTff7b72+Tff7b72+Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3isValidPathLenTb4b4b4(Te6edf3reply_path_lenTb4b4b4)Tb4b4b4) Tff7b72return T79c0ff0Tb4b4b4; T8b949e// reject - bad encoding
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3writePathTb4b4b4(Te6edf3reply_pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3reply_path_lenTb4b4b4)Tb4b4b4;
T8b949e// data += (uint8_t)reply_path_len * reply_path_hash_size;
Te6edf3memcpyTb4b4b4(Te6edf3reply_dataTb4b4b4, Tff7b72&Te6edf3sender_timestampTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// prefix with sender_timestamp, like a tag
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Tff7b72&Te6edf3nowTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// include our clock (for easy clock sync, and packet hash uniqueness)
Te6edf3reply_dataTb4b4b4[T79c0ff8Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// features
Tff7b72#Tff7b72ifdef WITH_RS232_BRIDGE
Te6edf3reply_dataTb4b4b4[T79c0ff8Tb4b4b4] Tff7b72|Tff7b72= T79c0ff0x01Tb4b4b4; T8b949e// is bridge, type UART
Tff7b72#Tff7b72elif WITH_ESPNOW_BRIDGE
Te6edf3reply_dataTb4b4b4[T79c0ff8Tb4b4b4] Tff7b72|Tff7b72= T79c0ff0x03Tb4b4b4; T8b949e// is bridge, type ESP-NOW
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3disable_fwdTb4b4b4) Tb4b4b4{ T8b949e// is this repeater currently disabled
Te6edf3reply_dataTb4b4b4[T79c0ff8Tb4b4b4] Tff7b72|Tff7b72= T79c0ff0x80Tb4b4b4; T8b949e// is disabled
Tb4b4b4}
T8b949e// TODO: add some kind of moving-window utilisation metric, so can query 'how busy' is this repeater
Tff7b72return T79c0ff9Tb4b4b4; T8b949e// reply length
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tffa657int Td2a8ffMyMesh::handleRequestTb4b4b4(Te6edf3ClientInfo Tff7b72*Te6edf3senderTb4b4b4, Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tffa657uint8_t Tff7b72*Te6edf3payloadTb4b4b4, Tffa657size_t Te6edf3payload_lenTb4b4b4) Tb4b4b4{
T8b949e// uint32_t now = getRTCClock()->getCurrentTimeUnique();
T8b949e// memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp
Te6edf3memcpyTb4b4b4(Te6edf3reply_dataTb4b4b4, Tff7b72&Te6edf3sender_timestampTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// reflect sender_timestamp back in response packet (kind of like a 'tag')
Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= Te6edf3REQ_TYPE_GET_STATUSTb4b4b4) Tb4b4b4{ T8b949e// guests can also access this now
Te6edf3RepeaterStats Te6edf3statsTb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3batt_milli_volts Tff7b72= Te6edf3boardTb4b4b4.Te6edf3getBattMilliVoltsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3curr_tx_queue_len Tff7b72= Te6edf3_mgrTff7b72-Tff7b72>Te6edf3getOutboundTotalTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3noise_floor Tff7b72= Tb4b4b4(Tffa657int16_tTb4b4b4)Te6edf3_radioTff7b72-Tff7b72>Te6edf3getNoiseFloorTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3last_rssi Tff7b72= Tb4b4b4(Tffa657int16_tTb4b4b4)Te6edf3radio_driverTb4b4b4.Te6edf3getLastRSSITb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3n_packets_recv Tff7b72= Te6edf3radio_driverTb4b4b4.Te6edf3getPacketsRecvTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3n_packets_sent Tff7b72= Te6edf3radio_driverTb4b4b4.Te6edf3getPacketsSentTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3total_air_time_secs Tff7b72= Te6edf3getTotalAirTimeTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1000Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3total_up_time_secs Tff7b72= Te6edf3uptime_millis Tff7b72/ T79c0ff1000Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3n_sent_flood Tff7b72= Te6edf3getNumSentFloodTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3n_sent_direct Tff7b72= Te6edf3getNumSentDirectTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3n_recv_flood Tff7b72= Te6edf3getNumRecvFloodTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3n_recv_direct Tff7b72= Te6edf3getNumRecvDirectTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3err_events Tff7b72= Te6edf3_err_flagsTb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3last_snr Tff7b72= Tb4b4b4(Tffa657int16_tTb4b4b4)Tb4b4b4(Te6edf3radio_driverTb4b4b4.Te6edf3getLastSNRTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3n_direct_dups Tff7b72= Tb4b4b4(Tb4b4b4(Te6edf3SimpleMeshTables Tff7b72*Tb4b4b4)Te6edf3getTablesTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getNumDirectDupsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3n_flood_dups Tff7b72= Tb4b4b4(Tb4b4b4(Te6edf3SimpleMeshTables Tff7b72*Tb4b4b4)Te6edf3getTablesTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getNumFloodDupsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3total_rx_air_time_secs Tff7b72= Te6edf3getReceiveAirTimeTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1000Tb4b4b4;
Te6edf3statsTb4b4b4.Te6edf3n_recv_errors Tff7b72= Te6edf3radio_driverTb4b4b4.Te6edf3getPacketsRecvErrorsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Tff7b72&Te6edf3statsTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3statsTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return T79c0ff4 Tff7b72+ Tff7b72sizeofTb4b4b4(Te6edf3statsTb4b4b4)Tb4b4b4; T8b949e// reply_len
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= Te6edf3REQ_TYPE_GET_TELEMETRY_DATATb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3perm_mask Tff7b72= Tff7b72~Tb4b4b4(Te6edf3payloadTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)Tb4b4b4; T8b949e// NEW: first reserved byte (of 4), is now inverse mask to apply to permissions
Te6edf3telemetryTb4b4b4.Te6edf3resetTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3telemetryTb4b4b4.Te6edf3addVoltageTb4b4b4(Te6edf3TELEM_CHANNEL_SELFTb4b4b4, Tb4b4b4(Tffa657floatTb4b4b4)Te6edf3boardTb4b4b4.Te6edf3getBattMilliVoltsTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1000.0fTb4b4b4)Tb4b4b4;
T8b949e// query other sensors -- target specific
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3senderTff7b72-Tff7b72>Te6edf3permissions Tff7b72& Te6edf3PERM_ACL_ROLE_MASKTb4b4b4) Tff7b72=Tff7b72= Te6edf3PERM_ACL_GUESTTb4b4b4) Tb4b4b4{
Te6edf3perm_mask Tff7b72= T79c0ff0x00Tb4b4b4; T8b949e// just base telemetry allowed
Tb4b4b4}
Te6edf3sensorsTb4b4b4.Te6edf3querySensorsTb4b4b4(Te6edf3perm_maskTb4b4b4, Te6edf3telemetryTb4b4b4)Tb4b4b4;
T8b949e// This default temperature will be overridden by external sensors (if any)
Tffa657float Te6edf3temperature Tff7b72= Te6edf3boardTb4b4b4.Te6edf3getMCUTemperatureTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72ifTb4b4b4(Tff7b72!Te6edf3isnanTb4b4b4(Te6edf3temperatureTb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// Supported boards with built-in temperature sensor. ESP32-C3 may return NAN
Te6edf3telemetryTb4b4b4.Te6edf3addTemperatureTb4b4b4(Te6edf3TELEM_CHANNEL_SELFTb4b4b4, Te6edf3temperatureTb4b4b4)Tb4b4b4; T8b949e// Built-in MCU Temperature
Tb4b4b4}
Tffa657uint8_t Te6edf3tlen Tff7b72= Te6edf3telemetryTb4b4b4.Te6edf3getSizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Te6edf3telemetryTb4b4b4.Te6edf3getBufferTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3tlenTb4b4b4)Tb4b4b4;
Tff7b72return T79c0ff4 Tff7b72+ Te6edf3tlenTb4b4b4; T8b949e// reply_len
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= Te6edf3REQ_TYPE_GET_ACCESS_LIST Tff7b72&Tff7b72& Te6edf3senderTff7b72-Tff7b72>Te6edf3isAdminTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3res1 Tff7b72= Te6edf3payloadTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4; T8b949e// reserved for future (extra query params)
Tffa657uint8_t Te6edf3res2 Tff7b72= Te6edf3payloadTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3res1 Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3res2 Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3ofs Tff7b72= T79c0ff4Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3aclTb4b4b4.Te6edf3getNumClientsTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3ofs Tff7b72+ T79c0ff7 Tff7b72<Tff7b72= Tff7b72sizeofTb4b4b4(Te6edf3reply_dataTb4b4b4) Tff7b72- T79c0ff4Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3c Tff7b72= Te6edf3aclTb4b4b4.Te6edf3getClientByIdxTb4b4b4(Te6edf3iTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cTff7b72-Tff7b72>Te6edf3permissions Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72continueTb4b4b4; T8b949e// skip deleted entries
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[Te6edf3ofsTb4b4b4]Tb4b4b4, Te6edf3cTff7b72-Tff7b72>Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, T79c0ff6Tb4b4b4)Tb4b4b4; Te6edf3ofs Tff7b72+Tff7b72= T79c0ff6Tb4b4b4; T8b949e// just 6-byte pub_key prefix
Te6edf3reply_dataTb4b4b4[Te6edf3ofsTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3cTff7b72-Tff7b72>Te6edf3permissionsTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3ofsTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= Te6edf3REQ_TYPE_GET_NEIGHBOURSTb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3request_version Tff7b72= Te6edf3payloadTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3request_version Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// reply data offset (after response sender_timestamp/tag)
Tffa657int Te6edf3reply_offset Tff7b72= T79c0ff4Tb4b4b4;
T8b949e// get request params
Tffa657uint8_t Te6edf3count Tff7b72= Te6edf3payloadTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4; T8b949e// how many neighbours to fetch (0-255)
Tffa657uint16_t Te6edf3offsetTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3offsetTb4b4b4, Tff7b72&Te6edf3payloadTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4; T8b949e// offset from start of neighbours list (0-65535)
Tffa657uint8_t Te6edf3order_by Tff7b72= Te6edf3payloadTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4; T8b949e// how to order neighbours. 0=newest_to_oldest, 1=oldest_to_newest, 2=strongest_to_weakest, 3=weakest_to_strongest
Tffa657uint8_t Te6edf3pubkey_prefix_length Tff7b72= Te6edf3payloadTb4b4b4[T79c0ff6Tb4b4b4]Tb4b4b4; T8b949e// how many bytes of neighbour pub key we want
T8b949e// we also send a 4 byte random blob in payload[7...10] to help packet uniqueness
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffREQ_TYPE_GET_NEIGHBOURS count=%d, offset=%d, order_by=%d, pubkey_prefix_length=%dTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4, Te6edf3offsetTb4b4b4, Te6edf3order_byTb4b4b4, Te6edf3pubkey_prefix_lengthTb4b4b4)Tb4b4b4;
T8b949e// clamp pub key prefix length to max pub key length
Tff7b72ifTb4b4b4(Te6edf3pubkey_prefix_length Tff7b72> Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4{
Te6edf3pubkey_prefix_length Tff7b72= Te6edf3PUB_KEY_SIZETb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffREQ_TYPE_GET_NEIGHBOURS invalid pubkey_prefix_length=%d clamping to %dTa5d6ff"Tb4b4b4, Te6edf3pubkey_prefix_lengthTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// create copy of neighbours list, skipping empty entries so we can sort it separately from main list
Tffa657int16_t Te6edf3neighbours_count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72#Tff7b72if MAX_NEIGHBOURS
Te6edf3NeighbourInfoTff7b72* Te6edf3sorted_neighboursTb4b4b4[Te6edf3MAX_NEIGHBOURSTb4b4b4]Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_NEIGHBOURSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3neighbour Tff7b72= Tff7b72&Te6edf3neighboursTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3neighbourTff7b72-Tff7b72>Te6edf3heard_timestamp Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3sorted_neighboursTb4b4b4[Te6edf3neighbours_countTb4b4b4] Tff7b72= Te6edf3neighbourTb4b4b4;
Te6edf3neighbours_countTff7b72+Tff7b72+Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// sort neighbours based on order
Tff7b72if Tb4b4b4(Te6edf3order_by Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// sort by newest to oldest
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffREQ_TYPE_GET_NEIGHBOURS sorting newest to oldestTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3sorted_neighboursTb4b4b4, Te6edf3sorted_neighbours Tff7b72+ Te6edf3neighbours_countTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3aTb4b4b4, Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3bTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3aTff7b72-Tff7b72>Te6edf3heard_timestamp Tff7b72> Te6edf3bTff7b72-Tff7b72>Te6edf3heard_timestampTb4b4b4; T8b949e// desc
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3order_by Tff7b72=Tff7b72= T79c0ff1Tb4b4b4) Tb4b4b4{
T8b949e// sort by oldest to newest
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffREQ_TYPE_GET_NEIGHBOURS sorting oldest to newestTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3sorted_neighboursTb4b4b4, Te6edf3sorted_neighbours Tff7b72+ Te6edf3neighbours_countTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3aTb4b4b4, Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3bTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3aTff7b72-Tff7b72>Te6edf3heard_timestamp Tff7b72< Te6edf3bTff7b72-Tff7b72>Te6edf3heard_timestampTb4b4b4; T8b949e// asc
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3order_by Tff7b72=Tff7b72= T79c0ff2Tb4b4b4) Tb4b4b4{
T8b949e// sort by strongest to weakest
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffREQ_TYPE_GET_NEIGHBOURS sorting strongest to weakestTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3sorted_neighboursTb4b4b4, Te6edf3sorted_neighbours Tff7b72+ Te6edf3neighbours_countTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3aTb4b4b4, Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3bTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3aTff7b72-Tff7b72>Te6edf3snr Tff7b72> Te6edf3bTff7b72-Tff7b72>Te6edf3snrTb4b4b4; T8b949e// desc
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3order_by Tff7b72=Tff7b72= T79c0ff3Tb4b4b4) Tb4b4b4{
T8b949e// sort by weakest to strongest
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffREQ_TYPE_GET_NEIGHBOURS sorting weakest to strongestTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3sorted_neighboursTb4b4b4, Te6edf3sorted_neighbours Tff7b72+ Te6edf3neighbours_countTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3aTb4b4b4, Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3bTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3aTff7b72-Tff7b72>Te6edf3snr Tff7b72< Te6edf3bTff7b72-Tff7b72>Te6edf3snrTb4b4b4; T8b949e// asc
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e// build results buffer
Tffa657int Te6edf3results_count Tff7b72= T79c0ff0Tb4b4b4;
Tffa657int Te6edf3results_offset Tff7b72= T79c0ff0Tb4b4b4;
Tffa657uint8_t Te6edf3results_bufferTb4b4b4[T79c0ff130Tb4b4b4]Tb4b4b4;
Tff7b72forTb4b4b4(Tffa657int Te6edf3index Tff7b72= T79c0ff0Tb4b4b4; Te6edf3index Tff7b72< Te6edf3count Tff7b72&Tff7b72& Te6edf3index Tff7b72+ Te6edf3offset Tff7b72< Te6edf3neighbours_countTb4b4b4; Te6edf3indexTff7b72+Tff7b72+Tb4b4b4)Tb4b4b4{
T8b949e// stop if we can't fit another entry in results
Tffa657int Te6edf3entry_size Tff7b72= Te6edf3pubkey_prefix_length Tff7b72+ T79c0ff4 Tff7b72+ T79c0ff1Tb4b4b4;
Tff7b72ifTb4b4b4(Te6edf3results_offset Tff7b72+ Te6edf3entry_size Tff7b72> Tff7b72sizeofTb4b4b4(Te6edf3results_bufferTb4b4b4)Tb4b4b4)Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffREQ_TYPE_GET_NEIGHBOURS no more entries can fit in results bufferTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if MAX_NEIGHBOURS
T8b949e// add next neighbour to results
Tff7b72auto Te6edf3neighbour Tff7b72= Te6edf3sorted_neighboursTb4b4b4[Te6edf3index Tff7b72+ Te6edf3offsetTb4b4b4]Tb4b4b4;
Tffa657uint32_t Te6edf3heard_seconds_ago Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3neighbourTff7b72-Tff7b72>Te6edf3heard_timestampTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3results_bufferTb4b4b4[Te6edf3results_offsetTb4b4b4]Tb4b4b4, Te6edf3neighbourTff7b72-Tff7b72>Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3pubkey_prefix_lengthTb4b4b4)Tb4b4b4; Te6edf3results_offset Tff7b72+Tff7b72= Te6edf3pubkey_prefix_lengthTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3results_bufferTb4b4b4[Te6edf3results_offsetTb4b4b4]Tb4b4b4, Tff7b72&Te6edf3heard_seconds_agoTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; Te6edf3results_offset Tff7b72+Tff7b72= T79c0ff4Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3results_bufferTb4b4b4[Te6edf3results_offsetTb4b4b4]Tb4b4b4, Tff7b72&Te6edf3neighbourTff7b72-Tff7b72>Te6edf3snrTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4; Te6edf3results_offset Tff7b72+Tff7b72= T79c0ff1Tb4b4b4;
Te6edf3results_countTff7b72+Tff7b72+Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e// build reply
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffREQ_TYPE_GET_NEIGHBOURS neighbours_count=%d results_count=%dTa5d6ff"Tb4b4b4, Te6edf3neighbours_countTb4b4b4, Te6edf3results_countTb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[Te6edf3reply_offsetTb4b4b4]Tb4b4b4, Tff7b72&Te6edf3neighbours_countTb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4; Te6edf3reply_offset Tff7b72+Tff7b72= T79c0ff2Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[Te6edf3reply_offsetTb4b4b4]Tb4b4b4, Tff7b72&Te6edf3results_countTb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4; Te6edf3reply_offset Tff7b72+Tff7b72= T79c0ff2Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3reply_dataTb4b4b4[Te6edf3reply_offsetTb4b4b4]Tb4b4b4, Tff7b72&Te6edf3results_bufferTb4b4b4, Te6edf3results_offsetTb4b4b4)Tb4b4b4; Te6edf3reply_offset Tff7b72+Tff7b72= Te6edf3results_offsetTb4b4b4;
Tff7b72return Te6edf3reply_offsetTb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= Te6edf3REQ_TYPE_GET_OWNER_INFOTb4b4b4) Tb4b4b4{
Te6edf3sprintfTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Ta5d6ff"Ta5d6ff%sTffea00\nTa5d6ff%sTffea00\nTa5d6ff%sTa5d6ff"Tb4b4b4, Te6edf3FIRMWARE_VERSIONTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3owner_infoTb4b4b4)Tb4b4b4;
Tff7b72return T79c0ff4 Tff7b72+ Te6edf3strlenTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3reply_dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4; T8b949e// unknown command
Tb4b4b4}
Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Td2a8ffMyMesh::createSelfAdvertTb4b4b4(Tb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3app_dataTb4b4b4[Te6edf3MAX_ADVERT_DATA_SIZETb4b4b4]Tb4b4b4;
Tffa657uint8_t Te6edf3app_data_len Tff7b72= Te6edf3_cliTb4b4b4.Te6edf3buildAdvertDataTb4b4b4(Te6edf3ADV_TYPE_REPEATERTb4b4b4, Te6edf3app_dataTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3createAdvertTb4b4b4(Te6edf3self_idTb4b4b4, Te6edf3app_dataTb4b4b4, Te6edf3app_data_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3File Td2a8ffMyMesh::openAppendTb4b4b4(Tff7b72const Tffa657char Tff7b72*Te6edf3fnameTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
Tff7b72return Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Te6edf3fnameTb4b4b4, Te6edf3FILE_O_WRITETb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(RP2040_PLATFORM)
Tff7b72return Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Te6edf3fnameTb4b4b4, Ta5d6ff"Ta5d6ffaTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Tff7b72return Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Te6edf3fnameTb4b4b4, Ta5d6ff"Ta5d6ffaTa5d6ff"Tb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72static Tffa657uint8_t Te6edf3max_loop_minimalTb4b4b4[Tb4b4b4] Tff7b72= Tb4b4b4{ T79c0ff0Tb4b4b4, T8b949e/* 1-byte */ T79c0ff4Tb4b4b4, T8b949e/* 2-byte */ T79c0ff2Tb4b4b4, T8b949e/* 3-byte */ T79c0ff1 Tb4b4b4}Tb4b4b4;
Tff7b72static Tffa657uint8_t Te6edf3max_loop_moderateTb4b4b4[Tb4b4b4] Tff7b72= Tb4b4b4{ T79c0ff0Tb4b4b4, T8b949e/* 1-byte */ T79c0ff2Tb4b4b4, T8b949e/* 2-byte */ T79c0ff1Tb4b4b4, T8b949e/* 3-byte */ T79c0ff1 Tb4b4b4}Tb4b4b4;
Tff7b72static Tffa657uint8_t Te6edf3max_loop_strictTb4b4b4[Tb4b4b4] Tff7b72= Tb4b4b4{ T79c0ff0Tb4b4b4, T8b949e/* 1-byte */ T79c0ff1Tb4b4b4, T8b949e/* 2-byte */ T79c0ff1Tb4b4b4, T8b949e/* 3-byte */ T79c0ff1 Tb4b4b4}Tb4b4b4;
Tffa657bool Td2a8ffMyMesh::isLoopedTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3packetTb4b4b4, Tff7b72const Tffa657uint8_t Te6edf3max_countersTb4b4b4[Tb4b4b4]Tb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3hash_size Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashSizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3hash_count Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashCountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3n Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72const Tffa657uint8_tTff7b72* Te6edf3path Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3hash_count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// count how many times this node is already in the path
Tff7b72if Tb4b4b4(Te6edf3self_idTb4b4b4.Te6edf3isHashMatchTb4b4b4(Te6edf3pathTb4b4b4, Te6edf3hash_sizeTb4b4b4)Tb4b4b4) Te6edf3nTff7b72+Tff7b72+Tb4b4b4;
Te6edf3hash_countTff7b72-Tff7b72-Tb4b4b4;
Te6edf3path Tff7b72+Tff7b72= Te6edf3hash_sizeTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3n Tff7b72>Tff7b72= Te6edf3max_countersTb4b4b4[Te6edf3hash_sizeTb4b4b4]Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::sendFloodReplyTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3packetTb4b4b4, Tffa657unsigned Tffa657long Te6edf3delay_millisTb4b4b4, Tffa657uint8_t Te6edf3path_hash_sizeTb4b4b4) Tb4b4b4{
Te6edf3TransportKey Te6edf3req_scopeTb4b4b4;
Tffa657bool Te6edf3is_wildcard Tff7b72= Te6edf3recv_pkt_region Tff7b72!Tff7b72= Tffa657NULL Tff7b72&Tff7b72& Te6edf3recv_pkt_regionTff7b72-Tff7b72>Te6edf3isWildcardTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3req_scope_known Tff7b72= Te6edf3recv_pkt_region Tff7b72!Tff7b72= Tffa657NULL Tff7b72&Tff7b72& Tff7b72!Te6edf3is_wildcard
Tff7b72&Tff7b72& Te6edf3region_mapTb4b4b4.Te6edf3getTransportKeysForTb4b4b4(Tff7b72*Te6edf3recv_pkt_regionTb4b4b4, Tff7b72&Te6edf3req_scopeTb4b4b4, T79c0ff1Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4;
Tff7b72switch Tb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3chooseReplyScopeTb4b4b4(Te6edf3req_scope_knownTb4b4b4, Te6edf3is_wildcardTb4b4b4, Tff7b72!Te6edf3default_scopeTb4b4b4.Te6edf3isNullTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72case Tff7b72meshTff7b72:Tff7b72:Tff7b72REPLY_SCOPE_REQUESTTb4b4b4:
Te6edf3sendFloodScopedTb4b4b4(Te6edf3req_scopeTb4b4b4, Te6edf3packetTb4b4b4, Te6edf3delay_millisTb4b4b4, Te6edf3path_hash_sizeTb4b4b4)Tb4b4b4; T8b949e// reply with same scope as request
Tff7b72breakTb4b4b4;
Tff7b72case Tff7b72meshTff7b72:Tff7b72:Tff7b72REPLY_SCOPE_DEFAULTTb4b4b4:
T8b949e// requester's scope is unknown: DIRECT request (no transport codes), or code matched no Region.
T8b949e// un-scoped would be dropped at hop 0 by repeaters running flood.max.unscoped=0
Te6edf3sendFloodScopedTb4b4b4(Te6edf3default_scopeTb4b4b4, Te6edf3packetTb4b4b4, Te6edf3delay_millisTb4b4b4, Te6edf3path_hash_sizeTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tff7b72case Tff7b72meshTff7b72:Tff7b72:Tff7b72REPLY_SCOPE_NONETb4b4b4:
Te6edf3sendFloodTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3delay_millisTb4b4b4, Te6edf3path_hash_sizeTb4b4b4)Tb4b4b4; T8b949e// send un-scoped
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657bool Td2a8ffMyMesh::allowPacketForwardTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3disable_fwdTb4b4b4) Tff7b72return Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4)
Tff7b72&Tff7b72& Te6edf3meshTff7b72:Tff7b72:Te6edf3isFloodHopLimitExceededTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3flood_maxTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3flood_max_unscopedTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3flood_max_advertTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3recv_pkt_region Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffallowPacketForward: unknown transport code, or wildcard not allowed for FLOOD packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3_prefsTb4b4b4.Te6edf3loop_detect Tff7b72!Tff7b72= Te6edf3LOOP_DETECT_OFFTb4b4b4) Tb4b4b4{
Tff7b72const Tffa657uint8_tTff7b72* Te6edf3maximumsTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3loop_detect Tff7b72=Tff7b72= Te6edf3LOOP_DETECT_MINIMALTb4b4b4) Tb4b4b4{
Te6edf3maximums Tff7b72= Te6edf3max_loop_minimalTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3loop_detect Tff7b72=Tff7b72= Te6edf3LOOP_DETECT_MODERATETb4b4b4) Tb4b4b4{
Te6edf3maximums Tff7b72= Te6edf3max_loop_moderateTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3maximums Tff7b72= Te6edf3max_loop_strictTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3isLoopedTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3maximumsTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffallowPacketForward: FLOOD packet loop detected!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72const Tffa657char Tff7b72*Td2a8ffMyMesh::getLogDateTimeTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72static Tffa657char Te6edf3tmpTb4b4b4[T79c0ff32Tb4b4b4]Tb4b4b4;
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DateTime Te6edf3dt Tff7b72= Te6edf3DateTimeTb4b4b4(Te6edf3nowTb4b4b4)Tb4b4b4;
Te6edf3sprintfTb4b4b4(Te6edf3tmpTb4b4b4, Ta5d6ff"Ta5d6ff%02d:%02d:%02d - %d/%d/%d UTa5d6ff"Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3hourTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3minuteTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3secondTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3dayTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3monthTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3dtTb4b4b4.Te6edf3yearTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3tmpTb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::logRxRawTb4b4b4(Tffa657float Te6edf3snrTb4b4b4, Tffa657float Te6edf3rssiTb4b4b4, Tff7b72const Tffa657uint8_t Te6edf3rawTb4b4b4[Tb4b4b4]Tb4b4b4, Tffa657int Te6edf3lenTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if MESH_PACKET_LOGGING
Te6edf3SerialTb4b4b4.Te6edf3printTb4b4b4(Te6edf3getLogDateTimeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printTb4b4b4(Ta5d6ff"Ta5d6ff RAW: Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3printHexTb4b4b4(Te6edf3SerialTb4b4b4, Te6edf3rawTb4b4b4, Te6edf3lenTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::logRxTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3pktTb4b4b4, Tffa657int Te6edf3lenTb4b4b4, Tffa657float Te6edf3scoreTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72ifdef WITH_BRIDGE
Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3bridge_pkt_src Tff7b72=Tff7b72= T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3bridgeTb4b4b4.Te6edf3sendPacketTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3_loggingTb4b4b4) Tb4b4b4{
Te6edf3File Te6edf3f Tff7b72= Te6edf3openAppendTb4b4b4(Te6edf3PACKET_LOG_FILETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3fTb4b4b4) Tb4b4b4{
Te6edf3fTb4b4b4.Te6edf3printTb4b4b4(Te6edf3getLogDateTimeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3fTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff: RX, len=%d (type=%d, route=%s, payload_len=%d) SNR=%d RSSI=%d score=%dTa5d6ff"Tb4b4b4, Te6edf3lenTb4b4b4,
Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3pktTff7b72-Tff7b72>Te6edf3isRouteDirectTb4b4b4(Tb4b4b4) Tff7b72? Ta5d6ff"Ta5d6ffDTa5d6ff" Tff7b72: Ta5d6ff"Ta5d6ffFTa5d6ff"Tb4b4b4, Te6edf3pktTff7b72-Tff7b72>Te6edf3payload_lenTb4b4b4,
Tb4b4b4(Tffa657intTb4b4b4)Te6edf3_radioTff7b72-Tff7b72>Te6edf3getLastSNRTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657intTb4b4b4)Te6edf3_radioTff7b72-Tff7b72>Te6edf3getLastRSSITb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Te6edf3score Tff7b72* T79c0ff1000Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_PATH Tff7b72|Tff7b72| Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_REQ Tff7b72|Tff7b72|
Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_RESPONSE Tff7b72|Tff7b72| Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_TXT_MSGTb4b4b4) Tb4b4b4{
Te6edf3fTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff [%02X -> %02X]Tffea00\nTa5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3pktTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3pktTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3fTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3fTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::logTxTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3pktTb4b4b4, Tffa657int Te6edf3lenTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72ifdef WITH_BRIDGE
Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3bridge_pkt_src Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3bridgeTb4b4b4.Te6edf3sendPacketTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3_loggingTb4b4b4) Tb4b4b4{
Te6edf3File Te6edf3f Tff7b72= Te6edf3openAppendTb4b4b4(Te6edf3PACKET_LOG_FILETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3fTb4b4b4) Tb4b4b4{
Te6edf3fTb4b4b4.Te6edf3printTb4b4b4(Te6edf3getLogDateTimeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3fTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff: TX, len=%d (type=%d, route=%s, payload_len=%d)Ta5d6ff"Tb4b4b4, Te6edf3lenTb4b4b4, Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3pktTff7b72-Tff7b72>Te6edf3isRouteDirectTb4b4b4(Tb4b4b4) Tff7b72? Ta5d6ff"Ta5d6ffDTa5d6ff" Tff7b72: Ta5d6ff"Ta5d6ffFTa5d6ff"Tb4b4b4, Te6edf3pktTff7b72-Tff7b72>Te6edf3payload_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_PATH Tff7b72|Tff7b72| Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_REQ Tff7b72|Tff7b72|
Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_RESPONSE Tff7b72|Tff7b72| Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_TXT_MSGTb4b4b4) Tb4b4b4{
Te6edf3fTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff [%02X -> %02X]Tffea00\nTa5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3pktTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3pktTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3fTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3fTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::logTxFailTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3pktTb4b4b4, Tffa657int Te6edf3lenTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_loggingTb4b4b4) Tb4b4b4{
Te6edf3File Te6edf3f Tff7b72= Te6edf3openAppendTb4b4b4(Te6edf3PACKET_LOG_FILETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3fTb4b4b4) Tb4b4b4{
Te6edf3fTb4b4b4.Te6edf3printTb4b4b4(Te6edf3getLogDateTimeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3fTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff: TX FAIL!, len=%d (type=%d, route=%s, payload_len=%d)Tffea00\nTa5d6ff"Tb4b4b4, Te6edf3lenTb4b4b4, Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3pktTff7b72-Tff7b72>Te6edf3isRouteDirectTb4b4b4(Tb4b4b4) Tff7b72? Ta5d6ff"Ta5d6ffDTa5d6ff" Tff7b72: Ta5d6ff"Ta5d6ffFTa5d6ff"Tb4b4b4, Te6edf3pktTff7b72-Tff7b72>Te6edf3payload_lenTb4b4b4)Tb4b4b4;
Te6edf3fTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657int Td2a8ffMyMesh::calcRxDelayTb4b4b4(Tffa657float Te6edf3scoreTb4b4b4, Tffa657uint32_t Te6edf3air_timeTb4b4b4) Tff7b72const Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3rx_delay_base Tff7b72<Tff7b72= T79c0ff0.0fTb4b4b4) Tff7b72return T79c0ff0Tb4b4b4;
Tff7b72return Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Tb4b4b4(Te6edf3powTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3rx_delay_baseTb4b4b4, T79c0ff0.85f Tff7b72- Te6edf3scoreTb4b4b4) Tff7b72- T79c0ff1.0Tb4b4b4) Tff7b72* Te6edf3air_timeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657uint32_t Td2a8ffMyMesh::getRetransmitDelayTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3packetTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3t Tff7b72= Tb4b4b4(Te6edf3_radioTff7b72-Tff7b72>Te6edf3getEstAirtimeForTb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathByteLenTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3packetTff7b72-Tff7b72>Te6edf3payload_len Tff7b72+ T79c0ff2Tb4b4b4) Tff7b72* Te6edf3_prefsTb4b4b4.Te6edf3tx_delay_factorTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3getRNGTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3nextIntTb4b4b4(T79c0ff0Tb4b4b4, T79c0ff5Tff7b72*Te6edf3t Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657uint32_t Td2a8ffMyMesh::getDirectRetransmitDelayTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3packetTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3t Tff7b72= Tb4b4b4(Te6edf3_radioTff7b72-Tff7b72>Te6edf3getEstAirtimeForTb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathByteLenTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3packetTff7b72-Tff7b72>Te6edf3payload_len Tff7b72+ T79c0ff2Tb4b4b4) Tff7b72* Te6edf3_prefsTb4b4b4.Te6edf3direct_tx_delay_factorTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3getRNGTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3nextIntTb4b4b4(T79c0ff0Tb4b4b4, T79c0ff5Tff7b72*Te6edf3t Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3meshTff7b72:Tff7b72:Te6edf3DispatcherAction Td2a8ffMyMesh::onRecvPacketTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getRouteTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ROUTE_TYPE_TRANSPORT_FLOODTb4b4b4) Tb4b4b4{
Te6edf3recv_pkt_region Tff7b72= Te6edf3region_mapTb4b4b4.Te6edf3findMatchTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3REGION_DENY_FLOODTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getRouteTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ROUTE_TYPE_FLOODTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3region_mapTb4b4b4.Te6edf3getWildcardTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3flags Tff7b72& Te6edf3REGION_DENY_FLOODTb4b4b4) Tb4b4b4{
Te6edf3recv_pkt_region Tff7b72= Tffa657NULLTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3recv_pkt_region Tff7b72= Tff7b72&Te6edf3region_mapTb4b4b4.Te6edf3getWildcardTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3recv_pkt_region Tff7b72= Tffa657NULLTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3MeshTff7b72:Tff7b72:Te6edf3onRecvPacketTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::onAnonDataRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3packetTb4b4b4, Tff7b72const Tffa657uint8_t Tff7b72*Te6edf3secretTb4b4b4, Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3Identity Tff7b72&Te6edf3senderTb4b4b4,
Tffa657uint8_t Tff7b72*Te6edf3dataTb4b4b4, Tffa657size_t Te6edf3lenTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_ANON_REQTb4b4b4) Tb4b4b4{ T8b949e// received an initial request by a possible admin
T8b949e// client (unknown at this stage)
Tffa657uint32_t Te6edf3timestampTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3timestampTb4b4b4, Te6edf3dataTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3dataTb4b4b4[Te6edf3lenTb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// ensure null terminator
Tffa657uint8_t Te6edf3reply_lenTb4b4b4;
Te6edf3reply_path_len Tff7b72= T79c0ff0xFFTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72=Tff7b72= T79c0ff0 Tff7b72|Tff7b72| Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72>Tff7b72= Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4) Tb4b4b4{ T8b949e// is password, ie. a login request
Te6edf3reply_len Tff7b72= Te6edf3handleLoginReqTb4b4b4(Te6edf3senderTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3timestampTb4b4b4, Tff7b72&Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72=Tff7b72= Te6edf3ANON_REQ_TYPE_REGIONS Tff7b72&Tff7b72& Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteDirectTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3reply_len Tff7b72= Te6edf3handleAnonRegionsReqTb4b4b4(Te6edf3senderTb4b4b4, Te6edf3timestampTb4b4b4, Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72=Tff7b72= Te6edf3ANON_REQ_TYPE_OWNER Tff7b72&Tff7b72& Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteDirectTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3reply_len Tff7b72= Te6edf3handleAnonOwnerReqTb4b4b4(Te6edf3senderTb4b4b4, Te6edf3timestampTb4b4b4, Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72=Tff7b72= Te6edf3ANON_REQ_TYPE_BASIC Tff7b72&Tff7b72& Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteDirectTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3reply_len Tff7b72= Te6edf3handleAnonClockReqTb4b4b4(Te6edf3senderTb4b4b4, Te6edf3timestampTb4b4b4, Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3reply_len Tff7b72= T79c0ff0Tb4b4b4; T8b949e// unknown/invalid request type
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3reply_len Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72returnTb4b4b4; T8b949e// invalid request
T8b949e// a DIRECT login can reply via the stored out_path, as onPeerDataRecv() does for REQ
Te6edf3ClientInfoTff7b72* Te6edf3client Tff7b72= Te6edf3aclTb4b4b4.Te6edf3getClientTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3have_out_path Tff7b72= Te6edf3client Tff7b72!Tff7b72= Tffa657NULL Tff7b72&Tff7b72& Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_len Tff7b72!Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4;
Tff7b72auto Te6edf3route Tff7b72= Te6edf3meshTff7b72:Tff7b72:Te6edf3chooseReplyRouteTb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3reply_path_len Tff7b72!Tff7b72= T79c0ff0xFFTb4b4b4, Te6edf3have_out_pathTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3route Tff7b72=Tff7b72= Te6edf3meshTff7b72:Tff7b72:Te6edf3REPLY_ROUTE_PATH_RETURNTb4b4b4) Tb4b4b4{
T8b949e// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3path Tff7b72= Te6edf3createPathReturnTb4b4b4(Te6edf3senderTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4,
Te6edf3PAYLOAD_TYPE_RESPONSETb4b4b4, Te6edf3reply_dataTb4b4b4, Te6edf3reply_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pathTb4b4b4) Te6edf3sendFloodReplyTb4b4b4(Te6edf3pathTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashSizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3reply Tff7b72= Te6edf3createDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_RESPONSETb4b4b4, Te6edf3senderTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3reply_dataTb4b4b4, Te6edf3reply_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3reply Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tff7b72returnTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3route Tff7b72=Tff7b72= Te6edf3meshTff7b72:Tff7b72:Te6edf3REPLY_ROUTE_DIRECT_SUPPLIEDTb4b4b4) Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3reply_pathTb4b4b4, Te6edf3reply_path_lenTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3route Tff7b72=Tff7b72= Te6edf3meshTff7b72:Tff7b72:Te6edf3REPLY_ROUTE_DIRECT_OUT_PATHTb4b4b4) Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3out_pathTb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_lenTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendFloodReplyTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashSizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657int Td2a8ffMyMesh::searchPeersByHashTb4b4b4(Tff7b72const Tffa657uint8_t Tff7b72*Te6edf3hashTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3n Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3aclTb4b4b4.Te6edf3getNumClientsTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3aclTb4b4b4.Te6edf3getClientByIdxTb4b4b4(Te6edf3iTb4b4b4)Tff7b72-Tff7b72>Te6edf3idTb4b4b4.Te6edf3isHashMatchTb4b4b4(Te6edf3hashTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3matching_peer_indexesTb4b4b4[Te6edf3nTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3iTb4b4b4; T8b949e// store the INDEXES of matching contacts (for subsequent 'peer' methods)
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3nTb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::getPeerSharedSecretTb4b4b4(Tffa657uint8_t Tff7b72*Te6edf3dest_secretTb4b4b4, Tffa657int Te6edf3peer_idxTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3i Tff7b72= Te6edf3matching_peer_indexesTb4b4b4[Te6edf3peer_idxTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72>Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3i Tff7b72< Te6edf3aclTb4b4b4.Te6edf3getNumClientsTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// lookup pre-calculated shared_secret
Te6edf3memcpyTb4b4b4(Te6edf3dest_secretTb4b4b4, Te6edf3aclTb4b4b4.Te6edf3getClientByIdxTb4b4b4(Te6edf3iTb4b4b4)Tff7b72-Tff7b72>Te6edf3shared_secretTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffgetPeerSharedSecret: Invalid peer idx: %dTa5d6ff"Tb4b4b4, Te6edf3iTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72static Tffa657bool Td2a8ffisShareTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3hasTransportCodesTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3packetTff7b72-Tff7b72>Te6edf3transport_codesTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3packetTff7b72-Tff7b72>Te6edf3transport_codesTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72=Tff7b72= T79c0ff0Tb4b4b4; T8b949e// codes { 0, 0 } means 'send to nowhere'
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::onAdvertRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3packetTb4b4b4, Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3Identity Tff7b72&Te6edf3idTb4b4b4, Tffa657uint32_t Te6edf3timestampTb4b4b4,
Tff7b72const Tffa657uint8_t Tff7b72*Te6edf3app_dataTb4b4b4, Tffa657size_t Te6edf3app_data_lenTb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3MeshTff7b72:Tff7b72:Te6edf3onAdvertRecvTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3idTb4b4b4, Te6edf3timestampTb4b4b4, Te6edf3app_dataTb4b4b4, Te6edf3app_data_lenTb4b4b4)Tb4b4b4; T8b949e// chain to super impl
T8b949e// if this a zero hop advert (and not via 'Share'), add it to neighbours
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashCountTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Tff7b72!Te6edf3isShareTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3AdvertDataParser Te6edf3parserTb4b4b4(Te6edf3app_dataTb4b4b4, Te6edf3app_data_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3parserTb4b4b4.Te6edf3isValidTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3parserTb4b4b4.Te6edf3getTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3ADV_TYPE_REPEATERTb4b4b4) Tb4b4b4{ T8b949e// just keep neigbouring Repeaters
Te6edf3putNeighbourTb4b4b4(Te6edf3idTb4b4b4, Te6edf3timestampTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3getSNRTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::onPeerDataRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3packetTb4b4b4, Tffa657uint8_t Te6edf3typeTb4b4b4, Tffa657int Te6edf3sender_idxTb4b4b4, Tff7b72const Tffa657uint8_t Tff7b72*Te6edf3secretTb4b4b4,
Tffa657uint8_t Tff7b72*Te6edf3dataTb4b4b4, Tffa657size_t Te6edf3lenTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3i Tff7b72= Te6edf3matching_peer_indexesTb4b4b4[Te6edf3sender_idxTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72< T79c0ff0 Tff7b72|Tff7b72| Te6edf3i Tff7b72>Tff7b72= Te6edf3aclTb4b4b4.Te6edf3getNumClientsTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// get from our known_clients table (sender SHOULD already be known in this context)
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonPeerDataRecv: invalid peer idx: %dTa5d6ff"Tb4b4b4, Te6edf3iTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3ClientInfoTff7b72* Te6edf3client Tff7b72= Te6edf3aclTb4b4b4.Te6edf3getClientByIdxTb4b4b4(Te6edf3iTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_REQTb4b4b4) Tb4b4b4{ T8b949e// request (from a Known admin client!)
Tffa657uint32_t Te6edf3timestampTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3timestampTb4b4b4, Te6edf3dataTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3timestamp Tff7b72> Te6edf3clientTff7b72-Tff7b72>Te6edf3last_timestampTb4b4b4) Tb4b4b4{ T8b949e// prevent replay attacks
Tffa657int Te6edf3reply_len Tff7b72= Te6edf3handleRequestTb4b4b4(Te6edf3clientTb4b4b4, Te6edf3timestampTb4b4b4, Tff7b72&Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Te6edf3len Tff7b72- T79c0ff4Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3reply_len Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72returnTb4b4b4; T8b949e// invalid command
Te6edf3clientTff7b72-Tff7b72>Te6edf3last_timestamp Tff7b72= Te6edf3timestampTb4b4b4;
Te6edf3clientTff7b72-Tff7b72>Te6edf3last_activity Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3path Tff7b72= Te6edf3createPathReturnTb4b4b4(Te6edf3clientTff7b72-Tff7b72>Te6edf3idTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4,
Te6edf3PAYLOAD_TYPE_RESPONSETb4b4b4, Te6edf3reply_dataTb4b4b4, Te6edf3reply_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pathTb4b4b4) Te6edf3sendFloodReplyTb4b4b4(Te6edf3pathTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashSizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3reply Tff7b72=
Te6edf3createDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_RESPONSETb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3idTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3reply_dataTb4b4b4, Te6edf3reply_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3replyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_len Tff7b72!Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{ T8b949e// we have an out_path, so send DIRECT
Te6edf3sendDirectTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3out_pathTb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_lenTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendFloodReplyTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashSizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonPeerDataRecv: possible replay attack detectedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_TXT_MSG Tff7b72&Tff7b72& Te6edf3len Tff7b72> T79c0ff5 Tff7b72&Tff7b72& Te6edf3clientTff7b72-Tff7b72>Te6edf3isAdminTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// a CLI command
Tffa657uint32_t Te6edf3sender_timestampTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3sender_timestampTb4b4b4, Te6edf3dataTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// timestamp (by sender's RTC clock - which could be wrong)
Tffa657uint8_t Te6edf3flags Tff7b72= Tb4b4b4(Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72>Tff7b72> T79c0ff2Tb4b4b4)Tb4b4b4; T8b949e// message attempt number, and other flags
Tff7b72if Tb4b4b4(Tff7b72!Tb4b4b4(Te6edf3flags Tff7b72=Tff7b72= Te6edf3TXT_TYPE_PLAIN Tff7b72|Tff7b72| Te6edf3flags Tff7b72=Tff7b72= Te6edf3TXT_TYPE_CLI_DATATb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonPeerDataRecv: unsupported text type received: flags=%02xTa5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3flagsTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3sender_timestamp Tff7b72>Tff7b72= Te6edf3clientTff7b72-Tff7b72>Te6edf3last_timestampTb4b4b4) Tb4b4b4{ T8b949e// prevent replay attacks
Tffa657bool Te6edf3is_retry Tff7b72= Tb4b4b4(Te6edf3sender_timestamp Tff7b72=Tff7b72= Te6edf3clientTff7b72-Tff7b72>Te6edf3last_timestampTb4b4b4)Tb4b4b4;
Te6edf3clientTff7b72-Tff7b72>Te6edf3last_timestamp Tff7b72= Te6edf3sender_timestampTb4b4b4;
Te6edf3clientTff7b72-Tff7b72>Te6edf3last_activity Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// len can be > original length, but 'text' will be padded with zeroes
Te6edf3dataTb4b4b4[Te6edf3lenTb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// need to make a C string again, with null terminator
Tff7b72if Tb4b4b4(Te6edf3flags Tff7b72=Tff7b72= Te6edf3TXT_TYPE_PLAINTb4b4b4) Tb4b4b4{ T8b949e// for legacy CLI, send Acks
Tffa657uint32_t Te6edf3ack_hashTb4b4b4; T8b949e// calc truncated hash of the message timestamp + text + sender pub_key, to prove
T8b949e// to sender that we got it
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3sha256Tb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4)Tff7b72&Te6edf3ack_hashTb4b4b4, T79c0ff4Tb4b4b4, Te6edf3dataTb4b4b4, T79c0ff5 Tff7b72+ Te6edf3strlenTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4)Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4,
Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3ack Tff7b72= Te6edf3createAckTb4b4b4(Te6edf3ack_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3ackTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3sendFloodReplyTb4b4b4(Te6edf3ackTb4b4b4, Te6edf3TXT_ACK_DELAYTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashSizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3ackTb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3out_pathTb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_lenTb4b4b4, Te6edf3TXT_ACK_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657uint8_t Te6edf3tempTb4b4b4[T79c0ff166Tb4b4b4]Tb4b4b4;
Tffa657char Tff7b72*Te6edf3command Tff7b72= Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4)Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4;
Tffa657char Tff7b72*Te6edf3reply Tff7b72= Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4)Tff7b72&Te6edf3tempTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_retryTb4b4b4) Tb4b4b4{
Tff7b72*Te6edf3reply Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3handleCommandTb4b4b4(Te6edf3sender_timestampTb4b4b4, Te6edf3commandTb4b4b4, Te6edf3replyTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657int Te6edf3text_len Tff7b72= Te6edf3strlenTb4b4b4(Te6edf3replyTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3text_len Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3timestamp Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeUniqueTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3timestamp Tff7b72=Tff7b72= Te6edf3sender_timestampTb4b4b4) Tb4b4b4{
T8b949e// WORKAROUND: the two timestamps need to be different, in the CLI view
Te6edf3timestampTff7b72+Tff7b72+Tb4b4b4;
Tb4b4b4}
Te6edf3memcpyTb4b4b4(Te6edf3tempTb4b4b4, Tff7b72&Te6edf3timestampTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// mostly an extra blob to help make packet_hash unique
Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72= Tb4b4b4(Te6edf3TXT_TYPE_CLI_DATA Tff7b72<Tff7b72< T79c0ff2Tb4b4b4)Tb4b4b4; T8b949e// NOTE: legacy was: TXT_TYPE_PLAIN
Tff7b72auto Te6edf3reply Tff7b72= Te6edf3createDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_TXT_MSGTb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3idTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3tempTb4b4b4, T79c0ff5 Tff7b72+ Te6edf3text_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3replyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3sendFloodReplyTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3CLI_REPLY_DELAY_MILLISTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashSizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3out_pathTb4b4b4, Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_lenTb4b4b4, Te6edf3CLI_REPLY_DELAY_MILLISTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonPeerDataRecv: possible replay attack detectedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657bool Td2a8ffMyMesh::onPeerPathRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3packetTb4b4b4, Tffa657int Te6edf3sender_idxTb4b4b4, Tff7b72const Tffa657uint8_t Tff7b72*Te6edf3secretTb4b4b4, Tffa657uint8_t Tff7b72*Te6edf3pathTb4b4b4,
Tffa657uint8_t Te6edf3path_lenTb4b4b4, Tffa657uint8_t Te6edf3extra_typeTb4b4b4, Tffa657uint8_t Tff7b72*Te6edf3extraTb4b4b4, Tffa657uint8_t Te6edf3extra_lenTb4b4b4) Tb4b4b4{
T8b949e// TODO: prevent replay attacks
Tffa657int Te6edf3i Tff7b72= Te6edf3matching_peer_indexesTb4b4b4[Te6edf3sender_idxTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72>Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3i Tff7b72< Te6edf3aclTb4b4b4.Te6edf3getNumClientsTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// get from our known_clients table (sender SHOULD already be known in this context)
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffPATH to client, path_len=%dTa5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3path_lenTb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3client Tff7b72= Te6edf3aclTb4b4b4.Te6edf3getClientByIdxTb4b4b4(Te6edf3iTb4b4b4)Tb4b4b4;
T8b949e// store a copy of path, for sendDirect()
Te6edf3clientTff7b72-Tff7b72>Te6edf3out_path_len Tff7b72= Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3copyPathTb4b4b4(Te6edf3clientTff7b72-Tff7b72>Te6edf3out_pathTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3path_lenTb4b4b4)Tb4b4b4;
Te6edf3clientTff7b72-Tff7b72>Te6edf3last_activity Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonPeerPathRecv: invalid peer idx: %dTa5d6ff"Tb4b4b4, Te6edf3iTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// NOTE: no reciprocal path send!!
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72define CTL_TYPE_NODE_DISCOVER_REQ 0x80
Tff7b72#Tff7b72define CTL_TYPE_NODE_DISCOVER_RESP 0x90
Tffa657void Td2a8ffMyMesh::onControlDataRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3packetTb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3type Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72& T79c0ff0xF0Tb4b4b4; T8b949e// just test upper 4 bits
Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3CTL_TYPE_NODE_DISCOVER_REQ Tff7b72&Tff7b72& Te6edf3packetTff7b72-Tff7b72>Te6edf3payload_len Tff7b72>Tff7b72= T79c0ff6
Tff7b72&Tff7b72& Tff7b72!Te6edf3_prefsTb4b4b4.Te6edf3disable_fwd Tff7b72&Tff7b72& Te6edf3discover_limiterTb4b4b4.Te6edf3allowTb4b4b4(Te6edf3rtc_clockTb4b4b4.Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4) Tb4b4b4{
Tffa657int Te6edf3i Tff7b72= T79c0ff1Tb4b4b4;
Tffa657uint8_t Te6edf3filter Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[Te6edf3iTff7b72+Tff7b72+Tb4b4b4]Tb4b4b4;
Tffa657uint32_t Te6edf3tagTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tagTb4b4b4, Tff7b72&Te6edf3packetTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; Te6edf3i Tff7b72+Tff7b72= T79c0ff4Tb4b4b4;
Tffa657uint32_t Te6edf3sinceTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3payload_len Tff7b72>Tff7b72= Te6edf3iTff7b72+T79c0ff4Tb4b4b4) Tb4b4b4{ T8b949e// optional since field
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3sinceTb4b4b4, Tff7b72&Te6edf3packetTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; Te6edf3i Tff7b72+Tff7b72= T79c0ff4Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3since Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3filter Tff7b72& Tb4b4b4(T79c0ff1 Tff7b72<Tff7b72< Te6edf3ADV_TYPE_REPEATERTb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3_prefsTb4b4b4.Te6edf3discovery_mod_timestamp Tff7b72>Tff7b72= Te6edf3sinceTb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3prefix_only Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72& T79c0ff1Tb4b4b4;
Tffa657uint8_t Te6edf3dataTb4b4b4[T79c0ff6 Tff7b72+ Te6edf3PUB_KEY_SIZETb4b4b4]Tb4b4b4;
Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= Te6edf3CTL_TYPE_NODE_DISCOVER_RESP Tff7b72| Te6edf3ADV_TYPE_REPEATERTb4b4b4; T8b949e// low 4-bits for node type
Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3_snrTb4b4b4; T8b949e// let sender know the inbound SNR ( x 4)
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3dataTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4, Tff7b72&Te6edf3tagTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// include tag from request, for client to match to
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3dataTb4b4b4[T79c0ff6Tb4b4b4]Tb4b4b4, Te6edf3self_idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3resp Tff7b72= Te6edf3createControlDataTb4b4b4(Te6edf3dataTb4b4b4, Te6edf3prefix_only Tff7b72? T79c0ff6 Tff7b72+ T79c0ff8 Tff7b72: T79c0ff6 Tff7b72+ Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3respTb4b4b4) Tb4b4b4{
Te6edf3sendZeroHopTb4b4b4(Te6edf3respTb4b4b4, Te6edf3getRetransmitDelayTb4b4b4(Te6edf3respTb4b4b4)Tff7b72*T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// apply random delay (widened x4), as multiple nodes can respond to this
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3CTL_TYPE_NODE_DISCOVER_RESP Tff7b72&Tff7b72& Te6edf3packetTff7b72-Tff7b72>Te6edf3payload_len Tff7b72>Tff7b72= T79c0ff6Tb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3node_type Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72& T79c0ff0x0FTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3node_type Tff7b72!Tff7b72= Te6edf3ADV_TYPE_REPEATERTb4b4b4) Tb4b4b4{
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3payload_len Tff7b72< T79c0ff6 Tff7b72+ Te6edf3PUB_KEY_SIZETb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonControlDataRecv: DISCOVER_RESP pubkey too short: %dTa5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3packetTff7b72-Tff7b72>Te6edf3payload_lenTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3pending_discover_tag Tff7b72=Tff7b72= T79c0ff0 Tff7b72|Tff7b72| Te6edf3millisHasNowPassedTb4b4b4(Te6edf3pending_discover_untilTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3pending_discover_tag Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tffa657uint32_t Te6edf3tagTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tagTb4b4b4, Tff7b72&Te6edf3packetTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3tag Tff7b72!Tff7b72= Te6edf3pending_discover_tagTb4b4b4) Tb4b4b4{
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3meshTff7b72:Tff7b72:Te6edf3Identity Te6edf3idTb4b4b4(Tff7b72&Te6edf3packetTff7b72-Tff7b72>Te6edf3payloadTb4b4b4[T79c0ff6Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3idTb4b4b4.Te6edf3matchesTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3putNeighbourTb4b4b4(Te6edf3idTb4b4b4, Te6edf3rtc_clockTb4b4b4.Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3getSNRTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffMyMesh::sendNodeDiscoverReqTb4b4b4(Tb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3dataTb4b4b4[T79c0ff10Tb4b4b4]Tb4b4b4;
Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= Te6edf3CTL_TYPE_NODE_DISCOVER_REQTb4b4b4; T8b949e// prefix_only=0
Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72= Tb4b4b4(T79c0ff1 Tff7b72<Tff7b72< Te6edf3ADV_TYPE_REPEATERTb4b4b4)Tb4b4b4;
Te6edf3getRNGTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3randomTb4b4b4(Tff7b72&Te6edf3dataTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// tag
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3pending_discover_tagTb4b4b4, Tff7b72&Te6edf3dataTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3pending_discover_until Tff7b72= Te6edf3futureMillisTb4b4b4(T79c0ff60000Tb4b4b4)Tb4b4b4;
Tffa657uint32_t Te6edf3since Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3dataTb4b4b4[T79c0ff6Tb4b4b4]Tb4b4b4, Tff7b72&Te6edf3sinceTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3createControlDataTb4b4b4(Te6edf3dataTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Te6edf3sendZeroHopTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3MyMeshTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3MainBoard Tff7b72&Te6edf3boardTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3Radio Tff7b72&Te6edf3radioTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3MillisecondClock Tff7b72&Te6edf3msTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3RNG Tff7b72&Te6edf3rngTb4b4b4,
Te6edf3meshTff7b72:Tff7b72:Te6edf3RTCClock Tff7b72&Te6edf3rtcTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3MeshTables Tff7b72&Te6edf3tablesTb4b4b4)
Tff7b72: Te6edf3meshTff7b72:Tff7b72:Te6edf3MeshTb4b4b4(Te6edf3radioTb4b4b4, Te6edf3msTb4b4b4, Te6edf3rngTb4b4b4, Te6edf3rtcTb4b4b4, Tff7b72*Tff7b72new Te6edf3StaticPoolPacketManagerTb4b4b4(T79c0ff32Tb4b4b4)Tb4b4b4, Te6edf3tablesTb4b4b4)Tb4b4b4,
Te6edf3region_mapTb4b4b4(Te6edf3key_storeTb4b4b4)Tb4b4b4, Te6edf3temp_mapTb4b4b4(Te6edf3key_storeTb4b4b4)Tb4b4b4,
Te6edf3_cliTb4b4b4(Te6edf3boardTb4b4b4, Te6edf3rtcTb4b4b4, Te6edf3sensorsTb4b4b4, Te6edf3region_mapTb4b4b4, Te6edf3aclTb4b4b4, Tff7b72&Te6edf3_prefsTb4b4b4, Tff7b72thisTb4b4b4)Tb4b4b4,
Te6edf3telemetryTb4b4b4(Te6edf3MAX_PACKET_PAYLOAD Tff7b72- T79c0ff4Tb4b4b4)Tb4b4b4,
Te6edf3discover_limiterTb4b4b4(T79c0ff4Tb4b4b4, T79c0ff120Tb4b4b4)Tb4b4b4, T8b949e// max 4 every 2 minutes
Te6edf3anon_limiterTb4b4b4(T79c0ff4Tb4b4b4, T79c0ff180Tb4b4b4) T8b949e// max 4 every 3 minutes
Tff7b72#Tff7b72if defined(WITH_RS232_BRIDGE)
Tb4b4b4, Te6edf3bridgeTb4b4b4(Tff7b72&Te6edf3_prefsTb4b4b4, Te6edf3WITH_RS232_BRIDGETb4b4b4, Te6edf3_mgrTb4b4b4, Tff7b72&Te6edf3rtcTb4b4b4)
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if defined(WITH_ESPNOW_BRIDGE)
Tb4b4b4, Te6edf3bridgeTb4b4b4(Tff7b72&Te6edf3_prefsTb4b4b4, Te6edf3_mgrTb4b4b4, Tff7b72&Te6edf3rtcTb4b4b4)
Tff7b72#Tff7b72endif
Tb4b4b4{
Te6edf3last_millis Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3uptime_millis Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3next_local_advert Tff7b72= Te6edf3next_flood_advert Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3dirty_contacts_expiry Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3set_radio_at Tff7b72= Te6edf3revert_radio_at Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3_logging Tff7b72= Tffa657falseTb4b4b4;
Te6edf3region_load_active Tff7b72= Tffa657falseTb4b4b4;
Te6edf3recv_pkt_region Tff7b72= Tffa657NULLTb4b4b4;
Tff7b72#Tff7b72if MAX_NEIGHBOURS
Te6edf3memsetTb4b4b4(Te6edf3neighboursTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3neighboursTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// defaults
Te6edf3_prefsTb4b4b4.Te6edf3airtime_factor Tff7b72= T79c0ff1.0Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3rx_delay_base Tff7b72= T79c0ff0.0fTb4b4b4; T8b949e// turn off by default, was 10.0;
Te6edf3_prefsTb4b4b4.Te6edf3tx_delay_factor Tff7b72= T79c0ff0.5fTb4b4b4; T8b949e// was 0.25f
Te6edf3_prefsTb4b4b4.Te6edf3direct_tx_delay_factor Tff7b72= T79c0ff0.3fTb4b4b4; T8b949e// was 0.2
Te6edf3StrHelperTff7b72:Tff7b72:Te6edf3strncpyTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Te6edf3ADVERT_NAMETb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3node_lat Tff7b72= Te6edf3ADVERT_LATTb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3node_lon Tff7b72= Te6edf3ADVERT_LONTb4b4b4;
Te6edf3StrHelperTff7b72:Tff7b72:Te6edf3strncpyTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3passwordTb4b4b4, Te6edf3ADMIN_PASSWORDTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3passwordTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3freq Tff7b72= Te6edf3LORA_FREQTb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3sf Tff7b72= Te6edf3LORA_SFTb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3bw Tff7b72= Te6edf3LORA_BWTb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3cr Tff7b72= Te6edf3LORA_CRTb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3tx_power_dbm Tff7b72= Te6edf3LORA_TX_POWERTb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3advert_interval Tff7b72= T79c0ff1Tb4b4b4; T8b949e// default to 2 minutes for NEW installs
Te6edf3_prefsTb4b4b4.Te6edf3flood_advert_interval Tff7b72= T79c0ff47Tb4b4b4; T8b949e// 47 hours
Te6edf3_prefsTb4b4b4.Te6edf3flood_max Tff7b72= T79c0ff64Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3flood_max_unscoped Tff7b72= T79c0ff64Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3flood_max_advert Tff7b72= T79c0ff8Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3interference_threshold Tff7b72= T79c0ff0Tb4b4b4; T8b949e// disabled
Te6edf3_prefsTb4b4b4.Te6edf3cad_enabled Tff7b72= T79c0ff0Tb4b4b4; T8b949e// hardware CAD before TX (off by default; 'set cad on')
T8b949e// bridge defaults
Te6edf3_prefsTb4b4b4.Te6edf3bridge_enabled Tff7b72= T79c0ff1Tb4b4b4; T8b949e// enabled
Te6edf3_prefsTb4b4b4.Te6edf3bridge_delay Tff7b72= T79c0ff500Tb4b4b4; T8b949e// milliseconds
Te6edf3_prefsTb4b4b4.Te6edf3bridge_pkt_src Tff7b72= T79c0ff0Tb4b4b4; T8b949e// logTx
Te6edf3_prefsTb4b4b4.Te6edf3bridge_baud Tff7b72= T79c0ff115200Tb4b4b4; T8b949e// baud rate
Te6edf3_prefsTb4b4b4.Te6edf3bridge_channel Tff7b72= T79c0ff1Tb4b4b4; T8b949e// channel 1
Te6edf3StrHelperTff7b72:Tff7b72:Te6edf3strncpyTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3bridge_secretTb4b4b4, Ta5d6ff"Ta5d6ffLVSITANOSTa5d6ff"Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3bridge_secretTb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// GPS defaults
Te6edf3_prefsTb4b4b4.Te6edf3gps_enabled Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3gps_interval Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3advert_loc_policy Tff7b72= Te6edf3ADVERT_LOC_PREFSTb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3adc_multiplier Tff7b72= T79c0ff0.0fTb4b4b4; T8b949e// 0.0f means use default board multiplier
Tff7b72#Tff7b72if defined(USE_SX1262) || defined(USE_SX1268)
Tff7b72#Tff7b72ifdef SX126X_RX_BOOSTED_GAIN
Te6edf3_prefsTb4b4b4.Te6edf3rx_boosted_gain Tff7b72= Te6edf3SX126X_RX_BOOSTED_GAINTb4b4b4;
Tff7b72#Tff7b72else
Te6edf3_prefsTb4b4b4.Te6edf3rx_boosted_gain Tff7b72= T79c0ff1Tb4b4b4; T8b949e// enabled by default;
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72endif
Te6edf3_prefsTb4b4b4.Te6edf3radio_fem_rxgain Tff7b72= T79c0ff1Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3radio_fem_txgain Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3pending_discover_tag Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3pending_discover_until Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3memsetTb4b4b4(Te6edf3default_scopeTb4b4b4.Te6edf3keyTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3default_scopeTb4b4b4.Te6edf3keyTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3beginTb4b4b4(Te6edf3FILESYSTEM Tff7b72*Te6edf3fsTb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3MeshTff7b72:Tff7b72:Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_fs Tff7b72= Te6edf3fsTb4b4b4;
T8b949e// load persisted prefs
Te6edf3_cliTb4b4b4.Te6edf3loadPrefsTb4b4b4(Te6edf3_fsTb4b4b4)Tb4b4b4;
Te6edf3aclTb4b4b4.Te6edf3loadTb4b4b4(Te6edf3_fsTb4b4b4, Te6edf3self_idTb4b4b4)Tb4b4b4;
T8b949e// TODO: key_store.begin();
Te6edf3region_mapTb4b4b4.Te6edf3loadTb4b4b4(Te6edf3_fsTb4b4b4)Tb4b4b4;
T8b949e// establish default-scope
Tb4b4b4{
Te6edf3RegionEntryTff7b72* Te6edf3r Tff7b72= Te6edf3region_mapTb4b4b4.Te6edf3getDefaultRegionTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3rTb4b4b4) Tb4b4b4{
Te6edf3region_mapTb4b4b4.Te6edf3getTransportKeysForTb4b4b4(Tff7b72*Te6edf3rTb4b4b4, Tff7b72&Te6edf3default_scopeTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72#Tff7b72ifdef DEFAULT_FLOOD_SCOPE_NAME
Te6edf3r Tff7b72= Te6edf3region_mapTb4b4b4.Te6edf3findByNameTb4b4b4(Te6edf3DEFAULT_FLOOD_SCOPE_NAMETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3r Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Te6edf3r Tff7b72= Te6edf3region_mapTb4b4b4.Te6edf3putRegionTb4b4b4(Te6edf3DEFAULT_FLOOD_SCOPE_NAMETb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4; T8b949e// auto-create the default scope region
Tff7b72if Tb4b4b4(Te6edf3rTb4b4b4) Tb4b4b4{ Te6edf3rTff7b72-Tff7b72>Te6edf3flags Tff7b72= T79c0ff0Tb4b4b4; Tb4b4b4} T8b949e// Allow-flood
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3rTb4b4b4) Tb4b4b4{
Te6edf3region_mapTb4b4b4.Te6edf3setDefaultRegionTb4b4b4(Te6edf3rTb4b4b4)Tb4b4b4;
Te6edf3region_mapTb4b4b4.Te6edf3getTransportKeysForTb4b4b4(Tff7b72*Te6edf3rTb4b4b4, Tff7b72&Te6edf3default_scopeTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72if defined(WITH_BRIDGE)
Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3bridge_enabledTb4b4b4) Tb4b4b4{
Te6edf3bridgeTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Te6edf3radio_driverTb4b4b4.Te6edf3setParamsTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3freqTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3bwTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3sfTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3crTb4b4b4)Tb4b4b4;
Te6edf3radio_driverTb4b4b4.Te6edf3setTxPowerTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3tx_power_dbmTb4b4b4)Tb4b4b4;
Te6edf3radio_driverTb4b4b4.Te6edf3setRxBoostedGainModeTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3rx_boosted_gainTb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffRX Boosted Gain Mode: %sTa5d6ff"Tb4b4b4,
Te6edf3radio_driverTb4b4b4.Te6edf3getRxBoostedGainModeTb4b4b4(Tb4b4b4) Tff7b72? Ta5d6ff"Ta5d6ffEnabledTa5d6ff" Tff7b72: Ta5d6ff"Ta5d6ffDisabledTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3boardTb4b4b4.Te6edf3setLoRaFemLnaEnabledTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3radio_fem_rxgainTb4b4b4)Tb4b4b4;
Te6edf3boardTb4b4b4.Te6edf3setLoRaFemPaGainEnabledTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3radio_fem_txgainTb4b4b4)Tb4b4b4;
Te6edf3updateAdvertTimerTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3updateFloodAdvertTimerTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3boardTb4b4b4.Te6edf3setAdcMultiplierTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3adc_multiplierTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if ENV_INCLUDE_GPS == 1
Te6edf3applyGpsPrefsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3sendFloodScopedTb4b4b4(Tff7b72const Te6edf3TransportKeyTff7b72& Te6edf3scopeTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4, Tffa657uint32_t Te6edf3delay_millisTb4b4b4, Tffa657uint8_t Te6edf3path_hash_sizeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3scopeTb4b4b4.Te6edf3isNullTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3sendFloodTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3delay_millisTb4b4b4, Te6edf3path_hash_sizeTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tffa657uint16_t Te6edf3codesTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4;
Te6edf3codesTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= Te6edf3scopeTb4b4b4.Te6edf3calcTransportCodeTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3codesTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// REVISIT: set to 'home' Region, for sender/return region?
Te6edf3sendFloodTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3codesTb4b4b4, Te6edf3delay_millisTb4b4b4, Te6edf3path_hash_sizeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3applyTempRadioParamsTb4b4b4(Tffa657float Te6edf3freqTb4b4b4, Tffa657float Te6edf3bwTb4b4b4, Tffa657uint8_t Te6edf3sfTb4b4b4, Tffa657uint8_t Te6edf3crTb4b4b4, Tffa657int Te6edf3timeout_minsTb4b4b4) Tb4b4b4{
Te6edf3set_radio_at Tff7b72= Te6edf3futureMillisTb4b4b4(T79c0ff2000Tb4b4b4)Tb4b4b4; T8b949e// give CLI reply some time to be sent back, before applying temp radio params
Te6edf3pending_freq Tff7b72= Te6edf3freqTb4b4b4;
Te6edf3pending_bw Tff7b72= Te6edf3bwTb4b4b4;
Te6edf3pending_sf Tff7b72= Te6edf3sfTb4b4b4;
Te6edf3pending_cr Tff7b72= Te6edf3crTb4b4b4;
Te6edf3revert_radio_at Tff7b72= Te6edf3futureMillisTb4b4b4(T79c0ff2000 Tff7b72+ Te6edf3timeout_mins Tff7b72* T79c0ff60 Tff7b72* T79c0ff1000Tb4b4b4)Tb4b4b4; T8b949e// schedule when to revert radio params
Tb4b4b4}
Tffa657bool Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3formatFileSystemTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
Tff7b72return Te6edf3InternalFSTb4b4b4.Te6edf3formatTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(RP2040_PLATFORM)
Tff7b72return Te6edf3LittleFSTb4b4b4.Te6edf3formatTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(ESP32)
Tff7b72return Te6edf3SPIFFSTb4b4b4.Te6edf3formatTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Tff7b72#Tff7b72error "need to implement file system erase"
Tff7b72return Tffa657falseTb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3sendSelfAdvertisementTb4b4b4(Tffa657int Te6edf3delay_millisTb4b4b4, Tffa657bool Te6edf3floodTb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3pkt Tff7b72= Te6edf3createSelfAdvertTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3floodTb4b4b4) Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3default_scopeTb4b4b4, Te6edf3pktTb4b4b4, Te6edf3delay_millisTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3path_hash_mode Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendZeroHopTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3delay_millisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffERROR: unable to create advertisement packet!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3updateAdvertTimerTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3advert_interval Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// schedule local advert timer
Te6edf3next_local_advert Tff7b72= Te6edf3futureMillisTb4b4b4(Tb4b4b4(Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3_prefsTb4b4b4.Te6edf3advert_intervalTb4b4b4) Tff7b72* T79c0ff2 Tff7b72* T79c0ff60 Tff7b72* T79c0ff1000Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3next_local_advert Tff7b72= T79c0ff0Tb4b4b4; T8b949e// stop the timer
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3updateFloodAdvertTimerTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3flood_advert_interval Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// schedule flood advert timer
Te6edf3next_flood_advert Tff7b72= Te6edf3futureMillisTb4b4b4(Tb4b4b4(Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3_prefsTb4b4b4.Te6edf3flood_advert_intervalTb4b4b4) Tff7b72* T79c0ff60 Tff7b72* T79c0ff60 Tff7b72* T79c0ff1000Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3next_flood_advert Tff7b72= T79c0ff0Tb4b4b4; T8b949e// stop the timer
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3dumpLogFileTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(RP2040_PLATFORM)
Te6edf3File Te6edf3f Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Te6edf3PACKET_LOG_FILETb4b4b4, Ta5d6ff"Ta5d6ffrTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3File Te6edf3f Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Te6edf3PACKET_LOG_FILETb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3fTb4b4b4) Tb4b4b4{
Tff7b72while Tb4b4b4(Te6edf3fTb4b4b4.Te6edf3availableTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657int Te6edf3c Tff7b72= Te6edf3fTb4b4b4.Te6edf3readTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3c Tff7b72< T79c0ff0Tb4b4b4) Tff7b72breakTb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printTb4b4b4(Tb4b4b4(Tffa657charTb4b4b4)Te6edf3cTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3fTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3setTxPowerTb4b4b4(Tffa657int8_t Te6edf3power_dbmTb4b4b4) Tb4b4b4{
Te6edf3radio_driverTb4b4b4.Te6edf3setTxPowerTb4b4b4(Te6edf3power_dbmTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657bool Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3setRxBoostedGainTb4b4b4(Tffa657bool Te6edf3enableTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3radio_driverTb4b4b4.Te6edf3setRxBoostedGainModeTb4b4b4(Te6edf3enableTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if defined(USE_LR2021)
Tffa657bool Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3configSideDetectorsTb4b4b4(Tff7b72const Tffa657uint8_t Te6edf3sideDetSFsTb4b4b4[Tb4b4b4]Tb4b4b4, Tffa657uint8_t Te6edf3numTb4b4b4, Tffa657float Te6edf3bwTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3radio_driverTb4b4b4.Te6edf3configSideDetectorsTb4b4b4(Te6edf3sideDetSFsTb4b4b4, Te6edf3numTb4b4b4, Te6edf3bwTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3formatNeighborsReplyTb4b4b4(Tffa657char Tff7b72*Te6edf3replyTb4b4b4) Tb4b4b4{
Tffa657char Tff7b72*Te6edf3dp Tff7b72= Te6edf3replyTb4b4b4;
Tff7b72#Tff7b72if MAX_NEIGHBOURS
T8b949e// create copy of neighbours list, skipping empty entries so we can sort it separately from main list
Tffa657int16_t Te6edf3neighbours_count Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3NeighbourInfoTff7b72* Te6edf3sorted_neighboursTb4b4b4[Te6edf3MAX_NEIGHBOURSTb4b4b4]Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_NEIGHBOURSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3neighbour Tff7b72= Tff7b72&Te6edf3neighboursTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3neighbourTff7b72-Tff7b72>Te6edf3heard_timestamp Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3sorted_neighboursTb4b4b4[Te6edf3neighbours_countTb4b4b4] Tff7b72= Te6edf3neighbourTb4b4b4;
Te6edf3neighbours_countTff7b72+Tff7b72+Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// sort neighbours newest to oldest
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3sorted_neighboursTb4b4b4, Te6edf3sorted_neighbours Tff7b72+ Te6edf3neighbours_countTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3aTb4b4b4, Tff7b72const Te6edf3NeighbourInfoTff7b72* Te6edf3bTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3aTff7b72-Tff7b72>Te6edf3heard_timestamp Tff7b72> Te6edf3bTff7b72-Tff7b72>Te6edf3heard_timestampTb4b4b4; T8b949e// desc
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3neighbours_count Tff7b72&Tff7b72& Te6edf3dp Tff7b72- Te6edf3reply Tff7b72< T79c0ff134Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3NeighbourInfo Tff7b72*Te6edf3neighbour Tff7b72= Te6edf3sorted_neighboursTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
T8b949e// add new line if not first item
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72> T79c0ff0Tb4b4b4) Tff7b72*Te6edf3dpTff7b72+Tff7b72+ Tff7b72= Ta5d6ff'Ta5d6ff\nTa5d6ff'Tb4b4b4;
Tffa657char Te6edf3hexTb4b4b4[T79c0ff10Tb4b4b4]Tb4b4b4;
T8b949e// get 4 bytes of neighbour id as hex
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3toHexTb4b4b4(Te6edf3hexTb4b4b4, Te6edf3neighbourTff7b72-Tff7b72>Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
T8b949e// add next neighbour
Tffa657uint32_t Te6edf3secs_ago Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3neighbourTff7b72-Tff7b72>Te6edf3heard_timestampTb4b4b4;
Te6edf3sprintfTb4b4b4(Te6edf3dpTb4b4b4, Ta5d6ff"Ta5d6ff%s:%d:%dTa5d6ff"Tb4b4b4, Te6edf3hexTb4b4b4, Te6edf3secs_agoTb4b4b4, Te6edf3neighbourTff7b72-Tff7b72>Te6edf3snrTb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Tff7b72*Te6edf3dpTb4b4b4)
Te6edf3dpTff7b72+Tff7b72+Tb4b4b4; T8b949e// find end of string
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3dp Tff7b72=Tff7b72= Te6edf3replyTb4b4b4) Tb4b4b4{ T8b949e// no neighbours, need empty response
Te6edf3strcpyTb4b4b4(Te6edf3dpTb4b4b4, Ta5d6ff"Ta5d6ff-none-Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3dp Tff7b72+Tff7b72= T79c0ff6Tb4b4b4;
Tb4b4b4}
Tff7b72*Te6edf3dp Tff7b72= T79c0ff0Tb4b4b4; T8b949e// null terminator
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3removeNeighborTb4b4b4(Tff7b72const Tffa657uint8_t Tff7b72*Te6edf3pubkeyTb4b4b4, Tffa657int Te6edf3key_lenTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if MAX_NEIGHBOURS
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_NEIGHBOURSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3NeighbourInfo Tff7b72*Te6edf3neighbour Tff7b72= Tff7b72&Te6edf3neighboursTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3neighbourTff7b72-Tff7b72>Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3pubkeyTb4b4b4, Te6edf3key_lenTb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3neighboursTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3NeighbourInfoTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// clear neighbour entry
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3startRegionsLoadTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3temp_mapTb4b4b4.Te6edf3resetFromTb4b4b4(Te6edf3region_mapTb4b4b4)Tb4b4b4; T8b949e// rebuild regions in a temp instance
Te6edf3memsetTb4b4b4(Te6edf3load_stackTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3load_stackTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3load_stackTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= Tff7b72&Te6edf3temp_mapTb4b4b4.Te6edf3getWildcardTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3region_load_active Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657bool Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3saveRegionsTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3region_mapTb4b4b4.Te6edf3saveTb4b4b4(Te6edf3_fsTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3onDefaultRegionChangedTb4b4b4(Tff7b72const Te6edf3RegionEntryTff7b72* Te6edf3rTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3rTb4b4b4) Tb4b4b4{
Te6edf3region_mapTb4b4b4.Te6edf3getTransportKeysForTb4b4b4(Tff7b72*Te6edf3rTb4b4b4, Tff7b72&Te6edf3default_scopeTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3memsetTb4b4b4(Te6edf3default_scopeTb4b4b4.Te6edf3keyTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3default_scopeTb4b4b4.Te6edf3keyTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3formatStatsReplyTb4b4b4(Tffa657char Tff7b72*Te6edf3replyTb4b4b4) Tb4b4b4{
Te6edf3StatsFormatHelperTff7b72:Tff7b72:Te6edf3formatCoreStatsTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3boardTb4b4b4, Tff7b72*Te6edf3_msTb4b4b4, Te6edf3_err_flagsTb4b4b4, Te6edf3_mgrTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3formatRadioStatsReplyTb4b4b4(Tffa657char Tff7b72*Te6edf3replyTb4b4b4) Tb4b4b4{
Te6edf3StatsFormatHelperTff7b72:Tff7b72:Te6edf3formatRadioStatsTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3_radioTb4b4b4, Te6edf3radio_driverTb4b4b4, Te6edf3getTotalAirTimeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3getReceiveAirTimeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3formatPacketStatsReplyTb4b4b4(Tffa657char Tff7b72*Te6edf3replyTb4b4b4) Tb4b4b4{
Te6edf3StatsFormatHelperTff7b72:Tff7b72:Te6edf3formatPacketStatsTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3radio_driverTb4b4b4, Te6edf3getNumSentFloodTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3getNumSentDirectTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3getNumRecvFloodTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3getNumRecvDirectTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3saveIdentityTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3LocalIdentity Tff7b72&Te6edf3new_idTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
Te6edf3IdentityStore Te6edf3storeTb4b4b4(Tff7b72*Te6edf3_fsTb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(ESP32)
Te6edf3IdentityStore Te6edf3storeTb4b4b4(Tff7b72*Te6edf3_fsTb4b4b4, Ta5d6ff"Ta5d6ff/identityTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(RP2040_PLATFORM)
Te6edf3IdentityStore Te6edf3storeTb4b4b4(Tff7b72*Te6edf3_fsTb4b4b4, Ta5d6ff"Ta5d6ff/identityTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Tff7b72#Tff7b72error "need to define saveIdentity()"
Tff7b72#Tff7b72endif
Te6edf3storeTb4b4b4.Te6edf3saveTb4b4b4(Ta5d6ff"Ta5d6ff_mainTa5d6ff"Tb4b4b4, Te6edf3new_idTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3clearStatsTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3radio_driverTb4b4b4.Te6edf3resetStatsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3resetStatsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4(Tb4b4b4(Te6edf3SimpleMeshTables Tff7b72*Tb4b4b4)Te6edf3getTablesTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72-Tff7b72>Te6edf3resetStatsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3handleCommandTb4b4b4(Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tffa657char Tff7b72*Te6edf3commandTb4b4b4, Tffa657char Tff7b72*Te6edf3replyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3region_load_activeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3StrHelperTff7b72:Tff7b72:Te6edf3isBlankTb4b4b4(Te6edf3commandTb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// empty/blank line, signal to terminate 'load' operation
Te6edf3region_map Tff7b72= Te6edf3temp_mapTb4b4b4; T8b949e// copy over the temp instance as new current map
Te6edf3region_load_active Tff7b72= Tffa657falseTb4b4b4;
Te6edf3sprintfTb4b4b4(Te6edf3replyTb4b4b4, Ta5d6ff"Ta5d6ffOK - loaded %d regionsTa5d6ff"Tb4b4b4, Te6edf3region_mapTb4b4b4.Te6edf3getCountTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tffa657char Tff7b72*Te6edf3np Tff7b72= Te6edf3commandTb4b4b4;
Tff7b72while Tb4b4b4(Tff7b72*Te6edf3np Tff7b72=Tff7b72= Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4) Te6edf3npTff7b72+Tff7b72+Tb4b4b4; T8b949e// skip indent
Tffa657int Te6edf3indent Tff7b72= Te6edf3np Tff7b72- Te6edf3commandTb4b4b4;
Tffa657char Tff7b72*Te6edf3ep Tff7b72= Te6edf3npTb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3RegionMapTff7b72:Tff7b72:Te6edf3is_name_charTb4b4b4(Tff7b72*Te6edf3epTb4b4b4)Tb4b4b4) Te6edf3epTff7b72+Tff7b72+Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72*Te6edf3epTb4b4b4) Tb4b4b4{ Tff7b72*Te6edf3epTff7b72+Tff7b72+ Tff7b72= T79c0ff0Tb4b4b4; Tb4b4b4} T8b949e// set null terminator for end of name
Tff7b72while Tb4b4b4(Tff7b72*Te6edf3ep Tff7b72&Tff7b72& Tff7b72*Te6edf3ep Tff7b72!Tff7b72= Ta5d6ff'Ta5d6ffFTa5d6ff'Tb4b4b4) Te6edf3epTff7b72+Tff7b72+Tb4b4b4; T8b949e// look for (optional) flags
Tff7b72if Tb4b4b4(Te6edf3indent Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3indent Tff7b72< T79c0ff8 Tff7b72&Tff7b72& Te6edf3strlenTb4b4b4(Te6edf3npTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3parent Tff7b72= Te6edf3load_stackTb4b4b4[Te6edf3indent Tff7b72- T79c0ff1Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3parentTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3old Tff7b72= Te6edf3region_mapTb4b4b4.Te6edf3findByNameTb4b4b4(Te6edf3npTb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3nw Tff7b72= Te6edf3temp_mapTb4b4b4.Te6edf3putRegionTb4b4b4(Te6edf3npTb4b4b4, Te6edf3parentTff7b72-Tff7b72>Te6edf3idTb4b4b4, Te6edf3old Tff7b72? Te6edf3oldTff7b72-Tff7b72>Te6edf3id Tff7b72: T79c0ff0Tb4b4b4)Tb4b4b4; T8b949e// carry-over the current ID (if name already exists)
Tff7b72if Tb4b4b4(Te6edf3nwTb4b4b4) Tb4b4b4{
Te6edf3nwTff7b72-Tff7b72>Te6edf3flags Tff7b72= Te6edf3old Tff7b72? Te6edf3oldTff7b72-Tff7b72>Te6edf3flags Tff7b72: Tb4b4b4(Tff7b72*Te6edf3ep Tff7b72=Tff7b72= Ta5d6ff'Ta5d6ffFTa5d6ff' Tff7b72? T79c0ff0 Tff7b72: Te6edf3REGION_DENY_FLOODTb4b4b4)Tb4b4b4; T8b949e// carry-over flags from curr
Te6edf3load_stackTb4b4b4[Te6edf3indentTb4b4b4] Tff7b72= Te6edf3nwTb4b4b4; T8b949e// keep pointers to parent regions, to resolve parent_id's
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3replyTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72while Tb4b4b4(Tff7b72*Te6edf3command Tff7b72=Tff7b72= Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4) Te6edf3commandTff7b72+Tff7b72+Tb4b4b4; T8b949e// skip leading spaces
Tff7b72if Tb4b4b4(Te6edf3strlenTb4b4b4(Te6edf3commandTb4b4b4) Tff7b72> T79c0ff4 Tff7b72&Tff7b72& Te6edf3commandTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72=Tff7b72= Ta5d6ff'Ta5d6ff|Ta5d6ff'Tb4b4b4) Tb4b4b4{ T8b949e// optional prefix (for companion radio CLI)
Te6edf3memcpyTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3commandTb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4; T8b949e// reflect the prefix back
Te6edf3reply Tff7b72+Tff7b72= T79c0ff3Tb4b4b4;
Te6edf3command Tff7b72+Tff7b72= T79c0ff3Tb4b4b4;
Tb4b4b4}
T8b949e// handle ACL related commands
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffsetperm Ta5d6ff"Tb4b4b4, T79c0ff8Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// format: setperm {pubkey-hex} {permissions-int8}
Tffa657charTff7b72* Te6edf3hex Tff7b72= Tff7b72&Te6edf3commandTb4b4b4[T79c0ff8Tb4b4b4]Tb4b4b4;
Tffa657charTff7b72* Te6edf3sp Tff7b72= Te6edf3strchrTb4b4b4(Te6edf3hexTb4b4b4, Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4)Tb4b4b4; T8b949e// look for separator char
Tff7b72if Tb4b4b4(Te6edf3sp Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Te6edf3strcpyTb4b4b4(Te6edf3replyTb4b4b4, Ta5d6ff"Ta5d6ffErr - bad paramsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72*Te6edf3spTff7b72+Tff7b72+ Tff7b72= T79c0ff0Tb4b4b4; T8b949e// replace space with null terminator
Tffa657uint8_t Te6edf3pubkeyTb4b4b4[Te6edf3PUB_KEY_SIZETb4b4b4]Tb4b4b4;
Tffa657int Te6edf3hex_len Tff7b72= Te6edf3minTb4b4b4(Te6edf3sp Tff7b72- Te6edf3hexTb4b4b4, Te6edf3PUB_KEY_SIZETff7b72*T79c0ff2Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3fromHexTb4b4b4(Te6edf3pubkeyTb4b4b4, Te6edf3hex_len Tff7b72/ T79c0ff2Tb4b4b4, Te6edf3hexTb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3perms Tff7b72= Te6edf3atoiTb4b4b4(Te6edf3spTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3aclTb4b4b4.Te6edf3applyPermissionsTb4b4b4(Te6edf3self_idTb4b4b4, Te6edf3pubkeyTb4b4b4, Te6edf3hex_len Tff7b72/ T79c0ff2Tb4b4b4, Te6edf3permsTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3dirty_contacts_expiry Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3LAZY_CONTACTS_WRITE_DELAYTb4b4b4)Tb4b4b4; T8b949e// trigger acl.save()
Te6edf3strcpyTb4b4b4(Te6edf3replyTb4b4b4, Ta5d6ff"Ta5d6ffOKTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3strcpyTb4b4b4(Te6edf3replyTb4b4b4, Ta5d6ff"Ta5d6ffErr - invalid paramsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3strcpyTb4b4b4(Te6edf3replyTb4b4b4, Ta5d6ff"Ta5d6ffErr - bad pubkeyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3sender_timestamp Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3strcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffget aclTa5d6ff"Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ffACL:Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3aclTb4b4b4.Te6edf3getNumClientsTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3c Tff7b72= Te6edf3aclTb4b4b4.Te6edf3getClientByIdxTb4b4b4(Te6edf3iTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cTff7b72-Tff7b72>Te6edf3permissions Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72continueTb4b4b4; T8b949e// skip deleted (or guest) entries
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff%02X Ta5d6ff"Tb4b4b4, Te6edf3cTff7b72-Tff7b72>Te6edf3permissionsTb4b4b4)Tb4b4b4;
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3printHexTb4b4b4(Te6edf3SerialTb4b4b4, Te6edf3cTff7b72-Tff7b72>Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3replyTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffdiscover.neighborsTa5d6ff"Tb4b4b4, T79c0ff18Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72const Tffa657charTff7b72* Te6edf3sub Tff7b72= Te6edf3command Tff7b72+ T79c0ff18Tb4b4b4;
Tff7b72while Tb4b4b4(Tff7b72*Te6edf3sub Tff7b72=Tff7b72= Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4) Te6edf3subTff7b72+Tff7b72+Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72*Te6edf3sub Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3strcpyTb4b4b4(Te6edf3replyTb4b4b4, Ta5d6ff"Ta5d6ffErr - discover.neighbors has no optionsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendNodeDiscoverReqTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3strcpyTb4b4b4(Te6edf3replyTb4b4b4, Ta5d6ff"Ta5d6ffOK - Discover sentTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72elseTb4b4b4{
Te6edf3_cliTb4b4b4.Te6edf3handleCommandTb4b4b4(Te6edf3sender_timestampTb4b4b4, Te6edf3commandTb4b4b4, Te6edf3replyTb4b4b4)Tb4b4b4; T8b949e// common CLI commands
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3loopTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72ifdef WITH_BRIDGE
Te6edf3bridgeTb4b4b4.Te6edf3loopTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3meshTff7b72:Tff7b72:Te6edf3MeshTff7b72:Tff7b72:Te6edf3loopTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3next_flood_advert Tff7b72&Tff7b72& Te6edf3millisHasNowPassedTb4b4b4(Te6edf3next_flood_advertTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3pkt Tff7b72= Te6edf3createSelfAdvertTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint32_t Te6edf3delay_millis Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Te6edf3sendFloodScopedTb4b4b4(Te6edf3default_scopeTb4b4b4, Te6edf3pktTb4b4b4, Te6edf3delay_millisTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3path_hash_mode Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3updateFloodAdvertTimerTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// schedule next flood advert
Te6edf3updateAdvertTimerTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// also schedule local advert (so they don't overlap)
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3next_local_advert Tff7b72&Tff7b72& Te6edf3millisHasNowPassedTb4b4b4(Te6edf3next_local_advertTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3Packet Tff7b72*Te6edf3pkt Tff7b72= Te6edf3createSelfAdvertTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Te6edf3sendZeroHopTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3updateAdvertTimerTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// schedule next local advert
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3set_radio_at Tff7b72&Tff7b72& Te6edf3millisHasNowPassedTb4b4b4(Te6edf3set_radio_atTb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// apply pending (temporary) radio params
Te6edf3set_radio_at Tff7b72= T79c0ff0Tb4b4b4; T8b949e// clear timer
Te6edf3radio_driverTb4b4b4.Te6edf3setParamsTb4b4b4(Te6edf3pending_freqTb4b4b4, Te6edf3pending_bwTb4b4b4, Te6edf3pending_sfTb4b4b4, Te6edf3pending_crTb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffTemp radio paramsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3revert_radio_at Tff7b72&Tff7b72& Te6edf3millisHasNowPassedTb4b4b4(Te6edf3revert_radio_atTb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// revert radio params to orig
Te6edf3revert_radio_at Tff7b72= T79c0ff0Tb4b4b4; T8b949e// clear timer
Te6edf3radio_driverTb4b4b4.Te6edf3setParamsTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3freqTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3bwTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3sfTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3crTb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffRadio params restoredTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// is pending dirty contacts write needed?
Tff7b72if Tb4b4b4(Te6edf3dirty_contacts_expiry Tff7b72&Tff7b72& Te6edf3millisHasNowPassedTb4b4b4(Te6edf3dirty_contacts_expiryTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3aclTb4b4b4.Te6edf3saveTb4b4b4(Te6edf3_fsTb4b4b4)Tb4b4b4;
Te6edf3dirty_contacts_expiry Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
T8b949e// update uptime
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3uptime_millis Tff7b72+Tff7b72= Te6edf3now Tff7b72- Te6edf3last_millisTb4b4b4;
Te6edf3last_millis Tff7b72= Te6edf3nowTb4b4b4;
Tb4b4b4}
T8b949e// To check if there is pending work
Tffa657bool Te6edf3MyMeshTff7b72:Tff7b72:Te6edf3hasPendingWorkTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{
Tff7b72#Tff7b72if defined(WITH_BRIDGE)
Tff7b72if Tb4b4b4(Te6edf3bridgeTb4b4b4.Te6edf3isRunningTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Tffa657trueTb4b4b4; T8b949e// bridge needs WiFi radio, can't sleep
Tff7b72#Tff7b72endif
Tff7b72return Te6edf3_mgrTff7b72-Tff7b72>Te6edf3getOutboundTotalTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4;
Tb4b4b4}
Served by rngit 1.5.2 - Generated in 0.59s